protogen, encoding/jsonpb, encoding/textpb: rename packages

Rename encoding/*pb to follow the convention of prefixing package names
with 'proto':

	google.golang.org/protobuf/encoding/protojson
	google.golang.org/protobuf/encoding/prototext

Move protogen under a compiler/ directory, just in case we ever do add
more compiler-related packages.

	google.golang.org/protobuf/compiler/protogen

Change-Id: I31010cb5cabcea8274fffcac468477b58b56e8eb
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/177178
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/encoding/prototext/encode.go b/encoding/prototext/encode.go
new file mode 100644
index 0000000..8f06370
--- /dev/null
+++ b/encoding/prototext/encode.go
@@ -0,0 +1,384 @@
+// Copyright 2018 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 prototext
+
+import (
+	"fmt"
+	"sort"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/internal/encoding/text"
+	"google.golang.org/protobuf/internal/encoding/wire"
+	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/fieldnum"
+	"google.golang.org/protobuf/internal/mapsort"
+	"google.golang.org/protobuf/internal/pragma"
+	"google.golang.org/protobuf/proto"
+	pref "google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+)
+
+// Marshal writes the given proto.Message in textproto format using default options.
+func Marshal(m proto.Message) ([]byte, error) {
+	return MarshalOptions{}.Marshal(m)
+}
+
+// MarshalOptions is a configurable text format marshaler.
+type MarshalOptions struct {
+	pragma.NoUnkeyedLiterals
+
+	// AllowPartial allows messages that have missing required fields to marshal
+	// without returning an error. If AllowPartial is false (the default),
+	// Marshal will return error if there are any missing required fields.
+	AllowPartial bool
+
+	// If Indent is a non-empty string, it causes entries for a Message to be
+	// preceded by the indent and trailed by a newline. Indent can only be
+	// composed of space or tab characters.
+	Indent string
+
+	// Resolver is the registry used for type lookups when marshaling out
+	// google.protobuf.Any messages in expanded form. If Resolver is not set,
+	// marshaling will default to using protoregistry.GlobalTypes.  If a type is
+	// not found, an Any message will be marshaled as a regular message.
+	Resolver *protoregistry.Types
+}
+
+// Marshal writes the given proto.Message in textproto format using options in MarshalOptions object.
+func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
+	if o.Resolver == nil {
+		o.Resolver = protoregistry.GlobalTypes
+	}
+
+	var nerr errors.NonFatal
+	v, err := o.marshalMessage(m.ProtoReflect())
+	if !nerr.Merge(err) {
+		return nil, err
+	}
+
+	delims := [2]byte{'{', '}'}
+	const outputASCII = false
+	b, err := text.Marshal(v, o.Indent, delims, outputASCII)
+	if !nerr.Merge(err) {
+		return nil, err
+	}
+	if !o.AllowPartial {
+		nerr.Merge(proto.IsInitialized(m))
+	}
+	return b, nerr.E
+}
+
+// marshalMessage converts a protoreflect.Message to a text.Value.
+func (o MarshalOptions) marshalMessage(m pref.Message) (text.Value, error) {
+	var nerr errors.NonFatal
+	var msgFields [][2]text.Value
+	messageDesc := m.Descriptor()
+
+	// Handle Any expansion.
+	if messageDesc.FullName() == "google.protobuf.Any" {
+		msg, err := o.marshalAny(m)
+		if err == nil || nerr.Merge(err) {
+			// Return as is for nil or non-fatal error.
+			return msg, nerr.E
+		}
+		// For other errors, continue on to marshal Any as a regular message.
+	}
+
+	// Handle known fields.
+	fieldDescs := messageDesc.Fields()
+	knownFields := m.KnownFields()
+	size := fieldDescs.Len()
+	for i := 0; i < size; i++ {
+		fd := fieldDescs.Get(i)
+		num := fd.Number()
+
+		if !knownFields.Has(num) {
+			continue
+		}
+
+		name := text.ValueOf(fd.Name())
+		// Use type name for group field name.
+		if fd.Kind() == pref.GroupKind {
+			name = text.ValueOf(fd.Message().Name())
+		}
+		pval := knownFields.Get(num)
+		var err error
+		msgFields, err = o.appendField(msgFields, name, pval, fd)
+		if !nerr.Merge(err) {
+			return text.Value{}, err
+		}
+	}
+
+	// Handle extensions.
+	var err error
+	msgFields, err = o.appendExtensions(msgFields, knownFields)
+	if !nerr.Merge(err) {
+		return text.Value{}, err
+	}
+
+	// Handle unknown fields.
+	// TODO: Provide option to exclude or include unknown fields.
+	m.UnknownFields().Range(func(_ pref.FieldNumber, raw pref.RawFields) bool {
+		msgFields = appendUnknown(msgFields, raw)
+		return true
+	})
+
+	return text.ValueOf(msgFields), nerr.E
+}
+
+// appendField marshals a protoreflect.Value and appends it to the given [][2]text.Value.
+func (o MarshalOptions) appendField(msgFields [][2]text.Value, name text.Value, pval pref.Value, fd pref.FieldDescriptor) ([][2]text.Value, error) {
+	var nerr errors.NonFatal
+
+	switch {
+	case fd.IsList():
+		items, err := o.marshalList(pval.List(), fd)
+		if !nerr.Merge(err) {
+			return msgFields, err
+		}
+
+		for _, item := range items {
+			msgFields = append(msgFields, [2]text.Value{name, item})
+		}
+	case fd.IsMap():
+		items, err := o.marshalMap(pval.Map(), fd)
+		if !nerr.Merge(err) {
+			return msgFields, err
+		}
+
+		for _, item := range items {
+			msgFields = append(msgFields, [2]text.Value{name, item})
+		}
+	default:
+		tval, err := o.marshalSingular(pval, fd)
+		if !nerr.Merge(err) {
+			return msgFields, err
+		}
+		msgFields = append(msgFields, [2]text.Value{name, tval})
+	}
+
+	return msgFields, nerr.E
+}
+
+// marshalSingular converts a non-repeated field value to text.Value.
+// This includes all scalar types, enums, messages, and groups.
+func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor) (text.Value, error) {
+	kind := fd.Kind()
+	switch kind {
+	case pref.BoolKind,
+		pref.Int32Kind, pref.Sint32Kind, pref.Uint32Kind,
+		pref.Int64Kind, pref.Sint64Kind, pref.Uint64Kind,
+		pref.Sfixed32Kind, pref.Fixed32Kind,
+		pref.Sfixed64Kind, pref.Fixed64Kind,
+		pref.FloatKind, pref.DoubleKind,
+		pref.BytesKind:
+		return text.ValueOf(val.Interface()), nil
+
+	case pref.StringKind:
+		s := val.String()
+		if utf8.ValidString(s) {
+			return text.ValueOf(s), nil
+		}
+		var nerr errors.NonFatal
+		nerr.AppendInvalidUTF8(string(fd.FullName()))
+		return text.ValueOf(s), nerr.E
+
+	case pref.EnumKind:
+		num := val.Enum()
+		if desc := fd.Enum().Values().ByNumber(num); desc != nil {
+			return text.ValueOf(desc.Name()), nil
+		}
+		// Use numeric value if there is no enum description.
+		return text.ValueOf(int32(num)), nil
+
+	case pref.MessageKind, pref.GroupKind:
+		return o.marshalMessage(val.Message())
+	}
+
+	panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind))
+}
+
+// marshalList converts a protoreflect.List to []text.Value.
+func (o MarshalOptions) marshalList(list pref.List, fd pref.FieldDescriptor) ([]text.Value, error) {
+	var nerr errors.NonFatal
+	size := list.Len()
+	values := make([]text.Value, 0, size)
+
+	for i := 0; i < size; i++ {
+		item := list.Get(i)
+		val, err := o.marshalSingular(item, fd)
+		if !nerr.Merge(err) {
+			// Return already marshaled values.
+			return values, err
+		}
+		values = append(values, val)
+	}
+
+	return values, nerr.E
+}
+
+var (
+	mapKeyName   = text.ValueOf(pref.Name("key"))
+	mapValueName = text.ValueOf(pref.Name("value"))
+)
+
+// marshalMap converts a protoreflect.Map to []text.Value.
+func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) ([]text.Value, error) {
+	var nerr errors.NonFatal
+	// values is a list of messages.
+	values := make([]text.Value, 0, mmap.Len())
+
+	var err error
+	mapsort.Range(mmap, fd.MapKey().Kind(), func(key pref.MapKey, val pref.Value) bool {
+		var keyTxtVal text.Value
+		keyTxtVal, err = o.marshalSingular(key.Value(), fd.MapKey())
+		if !nerr.Merge(err) {
+			return false
+		}
+		var valTxtVal text.Value
+		valTxtVal, err = o.marshalSingular(val, fd.MapValue())
+		if !nerr.Merge(err) {
+			return false
+		}
+		// Map entry (message) contains 2 fields, first field for key and second field for value.
+		msg := text.ValueOf([][2]text.Value{
+			{mapKeyName, keyTxtVal},
+			{mapValueName, valTxtVal},
+		})
+		values = append(values, msg)
+		err = nil
+		return true
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return values, nerr.E
+}
+
+// appendExtensions marshals extension fields and appends them to the given [][2]text.Value.
+func (o MarshalOptions) appendExtensions(msgFields [][2]text.Value, knownFields pref.KnownFields) ([][2]text.Value, error) {
+	xtTypes := knownFields.ExtensionTypes()
+	xtFields := make([][2]text.Value, 0, xtTypes.Len())
+
+	var nerr errors.NonFatal
+	var err error
+	xtTypes.Range(func(xt pref.ExtensionType) bool {
+		name := xt.Descriptor().FullName()
+		// If extended type is a MessageSet, set field name to be the message type name.
+		if isMessageSetExtension(xt) {
+			name = xt.Descriptor().Message().FullName()
+		}
+
+		num := xt.Descriptor().Number()
+		if knownFields.Has(num) {
+			// Use string type to produce [name] format.
+			tname := text.ValueOf(string(name))
+			pval := knownFields.Get(num)
+			xtFields, err = o.appendField(xtFields, tname, pval, xt.Descriptor())
+			if !nerr.Merge(err) {
+				return false
+			}
+			err = nil
+		}
+		return true
+	})
+	if err != nil {
+		return msgFields, err
+	}
+
+	// Sort extensions lexicographically and append to output.
+	sort.SliceStable(xtFields, func(i, j int) bool {
+		return xtFields[i][0].String() < xtFields[j][0].String()
+	})
+	return append(msgFields, xtFields...), nerr.E
+}
+
+// isMessageSetExtension reports whether extension extends a message set.
+func isMessageSetExtension(xt pref.ExtensionType) bool {
+	xd := xt.Descriptor()
+	if xd.Name() != "message_set_extension" {
+		return false
+	}
+	md := xd.Message()
+	if md == nil {
+		return false
+	}
+	if xd.FullName().Parent() != md.FullName() {
+		return false
+	}
+	xmd, ok := xd.ContainingMessage().(interface{ IsMessageSet() bool })
+	return ok && xmd.IsMessageSet()
+}
+
+// appendUnknown parses the given []byte and appends field(s) into the given fields slice.
+// This function assumes proper encoding in the given []byte.
+func appendUnknown(fields [][2]text.Value, b []byte) [][2]text.Value {
+	for len(b) > 0 {
+		var value interface{}
+		num, wtype, n := wire.ConsumeTag(b)
+		b = b[n:]
+
+		switch wtype {
+		case wire.VarintType:
+			value, n = wire.ConsumeVarint(b)
+		case wire.Fixed32Type:
+			value, n = wire.ConsumeFixed32(b)
+		case wire.Fixed64Type:
+			value, n = wire.ConsumeFixed64(b)
+		case wire.BytesType:
+			value, n = wire.ConsumeBytes(b)
+		case wire.StartGroupType:
+			var v []byte
+			v, n = wire.ConsumeGroup(num, b)
+			var msg [][2]text.Value
+			value = appendUnknown(msg, v)
+		default:
+			panic(fmt.Sprintf("error parsing unknown field wire type: %v", wtype))
+		}
+
+		fields = append(fields, [2]text.Value{text.ValueOf(uint32(num)), text.ValueOf(value)})
+		b = b[n:]
+	}
+	return fields
+}
+
+// marshalAny converts a google.protobuf.Any protoreflect.Message to a text.Value.
+func (o MarshalOptions) marshalAny(m pref.Message) (text.Value, error) {
+	var nerr errors.NonFatal
+	knownFields := m.KnownFields()
+	typeURL := knownFields.Get(fieldnum.Any_TypeUrl).String()
+	value := knownFields.Get(fieldnum.Any_Value)
+
+	emt, err := o.Resolver.FindMessageByURL(typeURL)
+	if !nerr.Merge(err) {
+		return text.Value{}, err
+	}
+	em := emt.New().Interface()
+	// TODO: Need to set types registry in binary unmarshaling.
+	// TODO: If binary unmarshaling returns required not set error, need to
+	// return another required not set error that contains both the path to this
+	// field and the path inside the embedded message.
+	err = proto.UnmarshalOptions{
+		AllowPartial: o.AllowPartial,
+	}.Unmarshal(value.Bytes(), em)
+	if !nerr.Merge(err) {
+		return text.Value{}, err
+	}
+
+	msg, err := o.marshalMessage(em.ProtoReflect())
+	if !nerr.Merge(err) {
+		return text.Value{}, err
+	}
+	// Expanded Any field value contains only a single field with the type_url field value as the
+	// field name in [] and a text marshaled field value of the embedded message.
+	msgFields := [][2]text.Value{
+		{
+			text.ValueOf(typeURL),
+			msg,
+		},
+	}
+	return text.ValueOf(msgFields), nerr.E
+}