Commit Graph

92 Commits

Author SHA1 Message Date
Joe Tsai
a31649d331 internal/impl: remove hack in legacy_extension_hack.go
This hack has now been upstreamed in the v1 codebase;
there is no longer any need to maintain the code in v2.
See https://github.com/golang/protobuf/pull/746

Change-Id: I2c59d11303f5465e65190d893c422c088c647691
Reviewed-on: https://go-review.googlesource.com/c/149659
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-15 02:11:35 +00:00
Joe Tsai
4b7aff630a all: rename Vector as List
The terminology Vector does not occur in protobuf documentation at all,
so we should rename the Go use of the term to something more recognizable.
As such, all instances that match the regexp "[Vv]ect(or)?" were replaced.

The C++ documentation uses the term "Repeated", which is a reasonable name.
However, the term became overloaded in 2014, when maps were added as a feature
and implementated under the hood as repeated fields. This is confusing as it
means "repeated" could either refer to repeated fields proper (i.e., explicitly
marked with the "repeated" label in the proto file) or map fields. In the case
of the C++ reflective API, this is not a problem since repeated fields proper
and map fields are interacted with through the same RepeatedField type.

In Go, we do not use a single type to handle both types of repeated fields:
1) We are coming up with the Go protobuf reflection API for the first time
and so do not need to piggy-back on the repeated fields API to remain backwards
compatible since no former usages of Go protobuf reflection exists.
2) Map fields are commonly represented in Go as the Go map type, which do not
preserve ordering information. As such it is fundamentally impossible to present
an unordered map as a consistently ordered list. Thus, Go needs two different
interfaces for lists and maps.

Given the above situation, "Repeated" is not a great term to use since it
refers to two different things (when we only want one of the meanings).
To distinguish between the two, we'll use the terms "List" and "Map" instead.
There is some precedence for the term "List" in the protobuf codebase
(e.g., "getRepeatedInt32List").

Change-Id: Iddcdb6b78e1e60c14fa4ca213c15f45e214b967b
Reviewed-on: https://go-review.googlesource.com/c/149657
Reviewed-by: Damien Neil <dneil@google.com>
2018-11-14 23:03:53 +00:00
Joe Tsai
f0c01e459b internal/impl: support legacy extension fields
Implement support for extension fields for messages that use the v1
data structures for extensions. The legacyExtensionFields type wraps a
v1 map to implement the v2 protoreflect.KnownFields interface.

Working on this change revealed a bug in the dynamic construction of
message types for protobuf messages that had cyclic dependencies (e.g.,
message Foo has a sub-field of message Bar, and Bar has a sub-field of Foo).
In such a situation, a deadlock occurs because initialization code depends on
the very initialization code that is currently running. To break these cycles,
we make some systematic changes listed in the following paragraphs.
Generally speaking, we separate the logic for construction and wrapping,
where constuction does not recursively rely on dependencies,
while wrapping may recursively inspect dependencies.

Promote the MessageType.MessageOf method as a standalone MessageOf function
that dynamically finds the proper *MessageType to use. We make it such that
MessageType only supports two forms of messages types:
* Those that fully implement the v2 API.
* Those that do not implement the v2 API at all.
This removes support for the hybrid form that was exploited by message_test.go

In impl/message_test.go, switch each message to look more like how future
generated messages will look like. This is done in reaction to the fact that
MessageType.MessageOf no longer exists.

In value/{map,vector}.go, fix Unwrap to return a pointer since the underlying
reflect.Value is addressable reference value, not a pointer value.

In value/convert.go, split the logic apart so that obtaining a v2 type and
wrapping a type as v2 are distinct operations. Wrapping requires further
initialization than simply creating the initial message type, and calling it
during initial construction would lead to a deadlock.

In protoreflect/go_type.go, we switch back to a lazy initialization of GoType
to avoid a deadlock since the user-provided fn may rely on the fact that
prototype.GoMessage returned.

Change-Id: I5dea00e36fe1a9899bd2ac0aed2c8e51d5d87420
Reviewed-on: https://go-review.googlesource.com/c/148826
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-14 18:37:45 +00:00
Joe Tsai
ea11813c05 internal/testprotos/legacy: initial commit
Add a corpus of generated protobuf messages generated at specific versions
of protoc-gen-go to ensure that we continue to support for generated messages
that have may never be updated.

Change-Id: I04a1b74306f471d7c99f5daf52399a5bd9adcbbc
Reviewed-on: https://go-review.googlesource.com/c/148831
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-13 22:37:52 +00:00
Joe Tsai
6f9095c675 internal/value: expose Converter.{MessageType,EnumType}
Rather than having the Converter carry a NewMessage method, have the struct
simply expose the MessageType or EnumType since they carry more information
and are retrieved anyways as part of the functionality of NewConverter.
While changing Converter, export the fields and remove all the methods.
Also, add an IsLegacy boolean, which is useful for the later implementation
of the extension fields.

Add a wrapLegacyEnum function which is used to wrap v1 enums as v2 enums.
We use this functionality in NewLegacyConverter to detrive the EnumType.
Additionally, modify wrapLegacyMessage to return a protoreflect.ProtoMessage
to be consistent with wrapLegacyEnum which must return a protoreflect.ProtoEnum.

Change-Id: Idc8989d07e4895d30de4ebc22c9ffa7357815cad
Reviewed-on: https://go-review.googlesource.com/c/148827
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-12 22:59:43 +00:00
Joe Tsai
1c40f4957d reflect/prototype: simplify Go type descriptor constructors
The Go type descriptors protoreflect.{Enum,Message,Extension}Type are simple
wrappers over protoreflect.{Enum,Message,Extension}Descriptor with a small
number of additional methods. It is very unlikely that more will be added in
the near future.

For this reason, construct the types directly using arguments to the constructor
function, as opposed to taking in another struct (which was originally done
to provide flexibility in-case we needed more fields).

Furthmore, rename GoNew and New.

Change-Id: Ic7fb5bc250cdb2761ae03b388b5147ff50f37d15
Reviewed-on: https://go-review.googlesource.com/c/148822
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-10 21:41:49 +00:00
Joe Tsai
34eb7ef6d5 reflect/protoreflect: clarify Clear and Remove operation on missing entries
Follow the precedence of Go maps where deletion on a key without an entry in
the map is a noop. Similarly, document that the following methods are safe
to call with entries that do not exist:
* Map.Clear
* KnownFields.Clear
* ExtensionFieldTypes.Remove

Change the implementation for each of these to match the documented behavior.

Change-Id: Ifccff9b7b03baaeffdc366d05f6286ba60e14934
Reviewed-on: https://go-review.googlesource.com/c/148317
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-08 02:34:04 +00:00
Joe Tsai
1795eb16a4 internal/impl: rename legacy_extension.go as legacy_extension_hack.go
The current logic in this file is temporary and will be removed.
Rename the file as legacy_extension_hack.go so that the future
legacy_extension.go file can contain the actual legacy code that cannot be
removed anytime in the near future.

Change-Id: I7edd9d682836379c4c97d18ea2c2a2e3b15db5a2
Reviewed-on: https://go-review.googlesource.com/c/147918
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-06 21:02:36 +00:00
Joe Tsai
88bc5a7d99 internal/value: extract Vector and Map logic as separate package
The implementation of reflect/protoreflect.NewGoExtension needs to be able to
provide a constructor for wrapping *[]T as a protoreflect.Vector.
However, it cannot depend on internal/impl since impl also depends on prototype.
Extract the common logic of Vector creation into a separate package that
has no dependencies on either impl or prototype.

Change-Id: I9295fde9b8861de11af085c91d9dfa56047d1b1e
Reviewed-on: https://go-review.googlesource.com/c/147446
Reviewed-by: Herbie Ong <herbie@google.com>
2018-11-06 01:20:32 +00:00
Joe Tsai
ce6edd3c71 internal/impl: support message and enum fields
Dynamically generate functions for handling message and enum fields,
regardless of whether they are of the v1 or v2 forms.

If a v1 message is encountered, it is automatically wrapped such that it
implements the v2 interface.

Change-Id: I457bc5286892e8fc00a61da7062dd33058daafd5
Reviewed-on: https://go-review.googlesource.com/c/143837
Reviewed-by: Damien Neil <dneil@google.com>
2018-11-05 22:25:52 +00:00
Joe Tsai
05828dba44 internal/encoding/tag: centralize logic for protobuf struct tag serialization
The bespoke text-serialization of field descriptors in protoc-gen-go is also
used in the legacy implementation of protobuf reflection to derive a
protoreflect.FieldDescriptor from legacy messages and also to convert to/from
protoreflect.ExtensionDescriptor and protoV1.ExtensionDesc.

Centralize this logic in a single place:
* to avoid reimplementing the same logic in internal/impl
* to keep the marshal and unmarshal logic co-located

Change-Id: I634c5afbb9dc6eda91d6cb6b0e68dbd724cb1ccb
Reviewed-on: https://go-review.googlesource.com/c/146758
Reviewed-by: Herbie Ong <herbie@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
2018-11-05 20:12:56 +00:00
Joe Tsai
95b0290ea8 internal/impl: support legacy unknown extension fields
The unknown fields in legacy messages is split across the XXX_unrecognized
field and also the XXX_InternalExtensions field. Implement support for
wrapping both fields and presenting it as if it were a unified set of
unknown fields.

Change-Id: If274fae2b48962520edd8a640080b6eced747684
Reviewed-on: https://go-review.googlesource.com/c/146517
Reviewed-by: Damien Neil <dneil@google.com>
2018-11-01 18:28:27 +00:00
Joe Tsai
2d5a169f75 internal/impl: use linked-list for unknown field ordering
Unknown fields follow a policy where the latest field takes precedence when
it comes to the ordering. However, the current implementation is incorrect
as it uses a slice and simply swaps the current entry with the last entry.
While this ensures that the latest field seen remains last, it does not ensure
that the swapped out entry is second-to-last.

To provide the desired behavior, a linked-list is used.
For simplicity, we use the list package in the standard library even if it
is neither the most performant nor type safe.

Change-Id: I675145c61f6b5b624ed9e94bbe2251b5a71e2c48
Reviewed-on: https://go-review.googlesource.com/c/145241
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-31 18:39:54 +00:00
Joe Tsai
e2afdc27e7 internal/impl: support legacy unknown fields
Add wrapper data structures to get legacy XXX_unrecognized fields to support
the new protoreflect.UnknownFields interface. This is a challenge since the
field is a []byte, which does not give us much flexibility to work with
in terms of choice of data structures.

This implementation is relatively naive where every operation is O(n) since
it needs to strip through the entire []byte each time. The Range operation
operates slightly differently from ranging over Go maps since it presents a
stale version of RawFields should a mutation occur while ranging.
This distinction is unlikely to affect anyone in practice.

Change-Id: Ib3247cb827f9a0dd6c2192cd59830dca5eef8257
Reviewed-on: https://go-review.googlesource.com/c/144697
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-26 19:55:21 +00:00
Joe Tsai
be5348c905 internal/impl: setup scaffolding for unknown and extension fields
Setup scaffolding for implementing unknown and extension fields.
Add functions to MessageType to produce a protoreflect.KnownFields or
protoreflect.UnknownFields from a message pointer.

Within the implementation of known fields, delegate the logic to the underlying
extension fields (which also implements protoreflect.KnownFields) if the field
number is not found in the set of defined fields.

Change-Id: I2c35f4cdf1c7b58727ce6a582861ef18b8d69a61
Reviewed-on: https://go-review.googlesource.com/c/144280
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-24 17:40:36 +00:00
Damien Neil
204f1c0ad8 reflect/protoreflect: add Descriptor.Options method
Add a method to fetch descriptor options. Since options are proto
messages (e.g., google.protobuf.FieldOptions), and proto message
packages depend on the protoreflect package, returning the actual option
type would cause a dependency cycle. Instead, we return an interface
value which can be type asserted to the appropriate concrete type.

Add options support to the prototype package.

Some of the prototype constructors included fields (such as
Field.IsPacked) which represent information from the options
(such as google.protobuf.FieldOptions.packed). To avoid confusion about
the canonical source of information, drop these fields in favor of the
options.

Drop the unimplemented Descriptor.DescriptorOptionsProto.

Change-Id: I66579b6a7d10d99eb6977402a247306a78913e74
Reviewed-on: https://go-review.googlesource.com/c/144277
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2018-10-23 23:44:11 +00:00
Joe Tsai
90fe996bd1 internal/impl: derive descriptors for legacy enums and messages
In order for the v2 rollout to be as seamless as possible, we need to support
the situation where a v2 message depends on some other generated v1 message that
may be stale and does not support the v2 API. In such a situation, there needs
to be some way to wrap a legacy message or enum in such a way that it satisfies
the v2 API.

This wrapping is comprised of two parts:
1) Deriving an enum or message descriptor
2) Providing an reflection implementation for messages

This CL addresses part 1 (while part 2 has already been partially implemented,
since the implementation applies to both v1 and v2).

To derive the enum and message descriptor we rely on a mixture of parsing the
raw descriptor proto and also introspection on the fields in the message.
Methods for obtaining the raw descriptor protos were added in February, 2016,
and so has not always been available. For that reason, we attempt to derive
as much information from the Go type as possible.

As part of this change, we modify prototype to be able to create multiple
standalone messages as a set. This is needed since cyclic dependencies is allowed
between messages within a single proto file.

Change-Id: I71aaf5f977faf9fba03c370b1ee17b3758ce60a6
Reviewed-on: https://go-review.googlesource.com/c/143539
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-22 17:18:39 +00:00
Joe Tsai
2c870bb5cc internal/impl: implement oneof fields
Dynamically generate functions for handling individual fields within an oneof.
This implementation uses Go reflection to interact with the currently generated
approach, which uses an interface that can only be set by a limited set of
wrapper structs.

Change-Id: Ic848df922d6547411a15c4a20bfbbcae362da5c0
Reviewed-on: https://go-review.googlesource.com/c/142895
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-17 22:20:50 +00:00
Joe Tsai
3903b218df reflect/protoreflect: remove List method
Remove List from KnownFields, UnknownFields, ExtensionFieldTypes, and Map.

Rationale:
* Each of those interfaces already have a Range method, which provides
a superset of the functionality of List. Furthermore, Range is more expressive
as it allows you to terminate iteration and provides both keys and values.
* List must always allocate a slice and populates it.
* Range is allocation free in some cases. For example, if you simply wanted to
iterate over all the populated fields to clear them, there is no need for a
closure, so a static version of the function can be directly referenced
(i.e., there is no need to create a stub function header that references the
closed-over variables).
* In the cases where a closure is needed, the allocation cost is O(1) since
there are a finite number of variables being closed over.
* In highly performance sensitive cases, the closured function could close over
a struct, such that the function and struct are stored in a sync.Pool when not
in use. For example:

	type MapLister struct {
		Entries []struct{K MapKey; V Value}
		f       func(MapKey, Value) true
	}
	func (m *MapLister) Ranger() func(MapKey, Value) bool {
		if m.f != nil {
			m.f = func(k MapKey, v Value) bool {
				m.Entries = append(m.Entries, ...)
				return true
			}
		}
		m.Entries = m.Entries[:0]
		return m.f
	}

The main benefit of List is the ease of use:

	for _, num := range knownFields.List() {
		...
	}

as opposed to:

	knownFields.Range(func(n FieldNumber, v Value) bool {
		...
		return true
	})

However, this is a marginal benefit.
Thus, remove List as it mostly inferior to Range.

Change-Id: I25586c6ea07a4706072ba06b1cf25cb6efb5e8a7
Reviewed-on: https://go-review.googlesource.com/c/142888
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-17 19:30:39 +00:00
Joe Tsai
bbfaeb77e5 internal/impl: implement Map fields
Generate functions for wrapping map[K]V to implement protoreflect.Map.
This implementation uses Go reflection instead to provide a single implementation
that can handle all Go map types.

Change-Id: Idcb8069ef836614a88e5df12ef7c5044e8aa3dea
Reviewed-on: https://go-review.googlesource.com/c/142778
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-17 17:45:34 +00:00
Joe Tsai
91e1466d6f internal/impl: implement Vector fields
Generate functions for wrapping []T to implement protoreflect.Vector.
This implementation uses Go reflection instead to provide a single implementation
that can handle all Go slice types.

The test harness was greatly expanded to be able to test vectors (in addition
to messages and maps in the near future).

Change-Id: I0106c175f84a1e7e0a0a5b0e02e2489b70b0d177
Reviewed-on: https://go-review.googlesource.com/c/135339
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-17 17:39:36 +00:00
Damien Neil
162c12703c protogen: generate .meta file with code annotations
When the generator parameter 'annotate_code' is provided, generate a .meta
file containing a GeneratedCodeInfo message describing the generated code's
relation to the source .proto file.

Annotations are added with (*protogen.GeneratedFile).Annotate, which takes the
name of a Go identifier (e.g., "SomeMessage" or "SomeMessage.GetField") and an
associated source location. The generator examines the generated AST to
determine source offsets for the symbols.

Change the []int32 "Path" in protogen types to a "Location", which also captures
the source file name.

Change-Id: Icd2340875831f40a1f91d495e3bd7ea381475c77
Reviewed-on: https://go-review.googlesource.com/c/139759
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2018-10-16 17:22:41 +00:00
Joe Tsai
c6b7561199 internal/impl: support wrapping Go structs to implement proto.Message
Given a pointer to a Go struct (that is well-formed according to the v1
struct field layout), wrap the type such that it implements the v2
protoreflect.Message interface.

Change-Id: I5987cad0d22e53970c613cdbbb1cfd4210897f69
Reviewed-on: https://go-review.googlesource.com/c/138897
Reviewed-by: Damien Neil <dneil@google.com>
2018-10-03 02:10:04 +00:00
Damien Neil
2dc6718b59 cmd/protoc-gen-go-grpc: add gRPC code generator
This is a straight translation of the v1 API gRPC "plugin" to protogen.

Add a protoc-gen-go-grpc command. The preferred way to generate gRPC
services is to invoke both plugins separately:

  protoc --go_out=. --go-grpc_out=. foo.proto

When invoked in this fashion, the generators will produce separate
foo.pb.go and foo_grpc.pb.go files.

Change-Id: Ie180385dab3da7063db96f7c2f9de3abbd749f63
Reviewed-on: https://go-review.googlesource.com/137037
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2018-09-27 19:32:34 +00:00
Joe Tsai
01ab29648e go.mod: rename google.golang.org/proto as github.com/golang/protobuf/v2
This change was created by running:
	git ls-files | xargs sed -i "s|google.golang.org/proto|github.com/golang/protobuf/v2|g"

This change is *not* an endorsement of "github.com/golang/protobuf/v2" as the
final import path when the v2 API is eventually released as stable.
We continue to reserve the right to make breaking changes as we see fit.

This change enables us to host the v2 API on a repository that is go-gettable
(since go.googlesource.com is not a known host by the "go get" tool;
and google.golang.org/proto was just a stub URL that is not currently served).
Thus, we can start work on a forked version of the v1 API that explores
what it would take to implement v1 in terms of v2 in a backwards compatible way.

Change-Id: Ia3ebc41ac4238af62ee140200d3158b53ac9ec48
Reviewed-on: https://go-review.googlesource.com/136736
Reviewed-by: Damien Neil <dneil@google.com>
2018-09-24 16:11:50 +00:00
Joe Tsai
ded92f8033 reflect/prototype: lower minimum support to Go1.9
The minimum supported version is currently Go1.10 since we use strings.Builder
for a fairly significant optimization when constructing all of the descriptor
full names.

The strings.Builder implementation is not particularly complicated,
so just fork it into our code. The golang/protobuf and the golang/go
projects share the same authors and copyright license.

Change-Id: Ibb9519dbe756327a07369f10f80c15761002b5e7
Reviewed-on: https://go-review.googlesource.com/136735
Reviewed-by: Damien Neil <dneil@google.com>
2018-09-21 19:30:05 +00:00
Joe Tsai
fa02f4eaa6 internal/impl: initial commit
This provides an implementation of the has, get, set, clear methods for each
field in a message. The approach taken here is similar to the table-driven
implementation in the current v1 proto package.

The pointer_reflect.go and pointer_unsafe.go files are a simplified version of
the same files in the v1 implementation. They provide a pointer abstraction
that enables a high-efficiency approach in a non-purego environment.
The unsafe fast-path is not implemented in this commit.

This commit only implements the accessor methods for scalars using pure
Go reflection.

Change-Id: Icdf707e9d4e3385e55434f93b30a341a7680ae11
Reviewed-on: https://go-review.googlesource.com/135136
Reviewed-by: Damien Neil <dneil@google.com>
2018-09-13 20:23:15 +00:00
Joe Tsai
8cb9190264 internal/encoding/pack: replace AST with CST in documentation
According to linguistics, this is actually a concrete syntax tree, rather
than an abstract syntax tree since it perfectly represents the grammatical
structure of the original raw input.

On the other hand, an abstract syntax tree (AST) loses some
grammatical structure and is only concerned with preserving syntax.

See https://eli.thegreenplace.net/2009/02/16/abstract-vs-concrete-syntax-trees/

Change-Id: Ia3fdb407d2b15c5431984956b7d74921891c2ad9
Reviewed-on: https://go-review.googlesource.com/133995
Reviewed-by: Herbie Ong <herbie@google.com>
2018-09-11 00:29:57 +00:00
Damien Neil
3de06c0868 reflect: add Index method to descriptor
Useful for dealing with SourceCodeInfo location paths, which identify
entities by their index.

Change-Id: I2034fc06b14c9b29b26e356fad21e106f63fbd14
Reviewed-on: https://go-review.googlesource.com/134115
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2018-09-07 17:57:37 +00:00
Joe Tsai
769b9e720b internal/cmd/pbdump: simplify and cleanup
Minor changes:
* Use spaces instead of tabs in help printout since each system may have
a different tab width.
* Reduce repetition for field flags.
* Print to stdout instead of stderr for flag usages as is customary for
most other Unix command line tools.

Change-Id: I4544dbf46ee150d552a8fdfe72683d0a1aa7f0ba
Reviewed-on: https://go-review.googlesource.com/133755
Reviewed-by: Herbie Ong <herbie@google.com>
2018-09-06 18:36:20 +00:00
Joe Tsai
b4e370ef3a internal/cmd/pbdump: initial commit
The pbdump binary is an internal-only command line tool that is similar
to the hexdump tool in Linux, but is tailored towards the protocol buffer
wire format. This tool is not necessary for the new API, but is very useful
for debugging the wire format.

Change-Id: Ie688338d33b01aee5dd88a63606ec0ffce57741d
Reviewed-on: https://go-review.googlesource.com/129405
Reviewed-by: Herbie Ong <herbie@google.com>
2018-09-04 03:30:39 +00:00
Joe Tsai
3ab648c9a8 internal/encoding/pack: initial commit
Package pack enables manual encoding and decoding of protobuf wire data.
This package is intended only for testing and debugging purposes.
Message.Marshal is useful for hand-crafting raw wire testdata in tests
in a readable form.
Message.Unmarshal is useful for parsing raw wire data for debugging.
For that reason, effort was put into trying to get its string formatted
output look humanly readable.

High-level API:
	type Number = wire.Number
		const MinValidNumber Number = wire.MinValidNumber ...
	type Type = wire.Type
		const VarintType Type = wire.VarintType ...

	type Token token
	type Tag struct { ... }
	type Bool bool
	type Varint int64
	type Svarint int64
	type Uvarint uint64
	type Int32 int32
	type Uint32 uint32
	type Float32 float32
	type Int64 int64
	type Uint64 uint64
	type Float64 float64
	type String string
	type Bytes []byte
	type LengthPrefix Message
	type Denormalized struct { ... }
	type Raw []byte

	type Message []Token
		func (Message) Size() int
		func (Message) Marshal() []byte
		func (*Message) Unmarshal(in []byte)
		func (*Message) UnmarshalDescriptor(in []byte, desc protoreflect.MessageDescriptor)
		func (Message) Format(s fmt.State, r rune)

Change-Id: Id99b340971a09c8a040838b155782a5d32b548bc
Reviewed-on: https://go-review.googlesource.com/129404
Reviewed-by: Herbie Ong <herbie@google.com>
2018-08-30 21:46:37 +00:00
Joe Tsai
bfda014ecd reflect/prototype: initial commit
The prototype package provides constructors to create protobuf types that
implement the interfaces defined in the protoreflect package.

High-level API:
	func NewFile(t *File) (protoreflect.FileDescriptor, error)
	type File struct{ ... }
	type Message struct{ ... }
	type Field struct{ ... }
	type Oneof struct{ ... }
	type Enum struct{ ... }
	type EnumValue struct{ ... }
	type Extension struct{ ... }
	type Service struct{ ... }
	type Method struct{ ... }

	func NewEnum(t *StandaloneEnum) (protoreflect.EnumDescriptor, error)
	func NewMessage(t *StandaloneMessage) (protoreflect.MessageDescriptor, error)
	func NewExtension(t *StandaloneExtension) (protoreflect.ExtensionDescriptor, error)
	type StandaloneEnum struct{ ... }
	type StandaloneMessage struct{ ... }
	type StandaloneExtension struct{ ... }

	func PlaceholderFile(path string, pkg protoreflect.FullName) protoreflect.FileDescriptor
	func PlaceholderEnum(name protoreflect.FullName) protoreflect.EnumDescriptor
	func PlaceholderMessage(name protoreflect.FullName) protoreflect.MessageDescriptor

This CL is missing some features that are to be added later:
* The stringer methods are not implemented, providing no way to print the
descriptors in a humanly readable manner.
* There is no support for proto options or retrieving the raw descriptor.
* There are constructors for Go specific types (e.g., protoreflect.MessageType).

We drop go1.9 support since we use strings.Builder.
We switch to go.11rc1 to obtain some bug fixes for modules.

Change-Id: Ieac9a2530afc81e5a5bb9ab5816804372f652b18
Reviewed-on: https://go-review.googlesource.com/129057
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Herbie Ong <herbie@google.com>
2018-08-15 18:44:04 +00:00
Joe Tsai
d55639e713 internal/set: add set package for set data structures
Package set provides simple set data structures for uint64 and string types.

High-level API:
	type Set(T {}) xxx
	func (Set) Len() int
	func (Set) Has(T) bool
	func (Set) Set(T)
	func (Set) Clear(T)

These data structures are useful for implementing required fields efficiently
or ensuring that protobuf identifiers do not conflict.

Change-Id: If846630a9034909a43121b3e0f6720275f4b7aaf
Reviewed-on: https://go-review.googlesource.com/128898
Reviewed-by: Chris Manghane <cmang@golang.org>
2018-08-09 21:46:35 +00:00
Joe Tsai
27c2a76c85 internal/encoding/text: initial commit of proto text format parser/serializer
Package text provides a parser and serializer for the proto text format.
This focuses on the grammar of the format and is agnostic towards specific
semantics of protobuf types.

High-level API:
	func Marshal(v Value, indent string, delims [2]byte, outputASCII bool) ([]byte, error)
	func Unmarshal(b []byte) (Value, error)
	type Type uint8
		const Bool Type ...
	type Value struct{ ... }
		func ValueOf(v interface{}) Value
		func (v Value) Type() Type
		func (v Value) Bool() (x bool, ok bool)
		func (v Value) Int(b64 bool) (x int64, ok bool)
		func (v Value) Uint(b64 bool) (x uint64, ok bool)
		func (v Value) Float(b64 bool) (x float64, ok bool)
		func (v Value) Name() (protoreflect.Name, bool)
		func (v Value) String() string
		func (v Value) List() []Value
		func (v Value) Message() [][2]Value
		func (v Value) Raw() []byte

Change-Id: I4a78ec4474c160d0de4d32120651edd931ea2c1e
Reviewed-on: https://go-review.googlesource.com/127455
Reviewed-by: Herbie Ong <herbie@google.com>
2018-08-07 22:44:06 +00:00
Joe Tsai
879b18d902 internal/encoding/json: initial commit of JSON parser/serializer
Package json provides a parser and serializer for the JSON format.
This focuses on the grammar of the format and is agnostic towards specific
semantics of protobuf types.

High-level API:
	func Marshal(v Value, indent string) ([]byte, error)
	func Unmarshal(b []byte) (Value, error)
	type Type uint8
	    const Null Type ...
	type Value struct{ ... }
	    func ValueOf(v interface{}) Value
		func (v Value) Type() Type
		func (v Value) Bool() bool
		func (v Value) Number() float64
		func (v Value) String() string
		func (v Value) Array() []Value
		func (v Value) Object() [][2]Value
		func (v Value) Raw() []byte

Change-Id: I26422f6b3881ef1a11b8aa95160645b1384b27b8
Reviewed-on: https://go-review.googlesource.com/127824
Reviewed-by: Herbie Ong <herbie@google.com>
2018-08-07 22:40:28 +00:00
Joe Tsai
ce91da5f05 internal/pragma: package to statically enforce certain properties
Package pragma provides certain constructs that can be used to statically enforce
certain language properties.

Change-Id: I58a87bf7429f3be1b5aae418595fadda32f9d039
Reviewed-on: https://go-review.googlesource.com/127822
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Herbie Ong <herbie@google.com>
2018-08-06 21:47:01 +00:00
Joe Tsai
0e6baaa2cb internal/encoding/wire: switch to use internal errors package
Change-Id: Ibb01f8a5d4dea09c19262f807e305bbebe0e6ab8
Reviewed-on: https://go-review.googlesource.com/127825
Reviewed-by: Herbie Ong <herbie@google.com>
2018-08-04 01:02:24 +00:00
Joe Tsai
025d81dac6 internal/flags: add package to control specialized functionality
Package flags defines a set of constants to control support for certain features.

Other flags that may be added in the future may include:
	PureGo: to control whether protobuf code should avoid using the unsafe
		package and only use Go reflection.
	PureProto: to control whether the proto package ignores the protoiface
		package and only uses protobuf reflection. This is useful for testing.
	Proto2ValidateUTF8: whether to validate UTF-8 in proto2 strings.
	Proto3ValidateUTF8: whether to validate UTF-8 in proto3 strings.

Change-Id: Ibcb8dd8b3e977633b8a4e4a22a0617f2eebcc325
Reviewed-on: https://go-review.googlesource.com/127820
Reviewed-by: Damien Neil <dneil@google.com>
2018-08-03 22:59:53 +00:00
Joe Tsai
be60f99ca7 internal/encoding/wire: fix minor miscategorization in test
Some of the test cases in TestFixed64 actually belong in TestBytes.

Change-Id: I7f3efd77662881b64a96311161440fd220ae8074
Reviewed-on: https://go-review.googlesource.com/127456
Reviewed-by: Chris Manghane <cmang@golang.org>
2018-08-02 21:53:01 +00:00
Joe Tsai
9834a7df51 internal/errors: initial commit
This adds package errors, which provides error handling constructs that are
specific to the protobuf repo. In particular, it provides a NonFatal type
which is useful for capturing non-fatal errors like invalid UTF-8 and required
fields not set.

High-level API:
	type NonFatalErrors []error
		func (NonFatalErrors) Error() string
	type NonFatal struct{ ... }
		func (*NonFatal) Merge(err error) (ok bool)
		func (*NonFatal) AppendInvalidUTF8(field string)
		func (*NonFatal) AppendRequiredNotSet(field string)
	func New(string, ...interface{}) error

Change-Id: I9448c586008240e8987573fe79e0ffb024e7629d
Reviewed-on: https://go-review.googlesource.com/127338
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Herbie Ong <herbie@google.com>
2018-08-02 18:28:47 +00:00
Joe Tsai
22505a4929 internal/encoding/wire: initial commit
This adds package wire, which provides low-level functionality for
marshaling and unmarshaling the protobuf wire format.

High-level API:
	type Number int32
	    const MinValidNumber Number = 1 ...
	type Type int8
	    const VarintType Type = 0 ...
	func ParseError(n int) error

	func ConsumeField(b []byte) (Number, Type, int)
	func ConsumeFieldValue(num Number, typ Type, b []byte) (n int)
	func ConsumeTag(b []byte) (Number, Type, int)
	func ConsumeVarint(b []byte) (v uint64, n int)
	func ConsumeFixed32(b []byte) (v uint32, n int)
	func ConsumeFixed64(b []byte) (v uint64, n int)
	func ConsumeBytes(b []byte) (v []byte, n int)
	func ConsumeGroup(num Number, b []byte) (v []byte, n int)
	func AppendTag(b []byte, num Number, typ Type) []byte
	func AppendVarint(b []byte, v uint64) []byte
	func AppendFixed32(b []byte, v uint32) []byte
	func AppendFixed64(b []byte, v uint64) []byte
	func AppendBytes(b []byte, v []byte) []byte
	func AppendGroup(b []byte, num Number, v []byte) []byte
	func SizeTag(num Number) int
	func SizeVarint(v uint64) int
	func SizeFixed32() int
	func SizeFixed64() int
	func SizeBytes(n int) int
	func SizeGroup(num Number, n int) int

	func DecodeBool(x uint64) bool
	func DecodeTag(x uint64) (Number, Type)
	func DecodeZigZag(x uint64) int64
	func EncodeBool(x bool) uint64
	func EncodeTag(num Number, typ Type) uint64
	func EncodeZigZag(x int64) uint64

Change-Id: I052d8975414aeb182f6e9595c4736e716f1b7e9d
Reviewed-on: https://go-review.googlesource.com/127337
Reviewed-by: Chris Manghane <cmang@golang.org>
Run-TryBot: Chris Manghane <cmang@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-08-01 23:02:07 +00:00