internal/impl: add MessageState to every generated message

We define MessageState, which is essentially an atomically set *MessageInfo.
By nesting this as the first field in every generated message, we can
implement the reflective methods on a *MessageState when obtained by
unsafe casting a concrete message pointer as a *MessageState.
The MessageInfo held by MessageState provides additional Go type information
to interpret the memory that comes after the contents of the MessageState.

Since we are nesting a MessageState in every message,
the memory use of every message instance grows by 8B.

On average, the body of ProtoReflect grows from 133B to 202B (+50%).
However, this is offset by XXX_Methods, which is 108B and
will be removed in a future CL. Taking into account the eventual removal
of XXX_Methods, this is a net reduction of 25%.

name          old time/op    new time/op    delta
Name/Value-4    70.3ns ± 2%    17.5ns ± 6%   -75.08%  (p=0.000 n=10+10)
Name/Nil-4      70.6ns ± 3%    33.4ns ± 2%   -52.66%  (p=0.000 n=10+10)

name          old alloc/op   new alloc/op   delta
Name/Value-4     16.0B ± 0%      0.0B       -100.00%  (p=0.000 n=10+10)
Name/Nil-4       16.0B ± 0%      0.0B       -100.00%  (p=0.000 n=10+10)

name          old allocs/op  new allocs/op  delta
Name/Value-4      1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)
Name/Nil-4        1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)

Change-Id: I92bd58dc681c57c92612fd5ba7fc066aea34e95a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185460
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/message_reflect_gen.go b/internal/impl/message_reflect_gen.go
new file mode 100644
index 0000000..41ba0b9
--- /dev/null
+++ b/internal/impl/message_reflect_gen.go
@@ -0,0 +1,190 @@
+// 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.
+
+// Code generated by generate-types. DO NOT EDIT.
+
+package impl
+
+import (
+	"google.golang.org/protobuf/reflect/protoreflect"
+)
+
+func (m *messageState) Descriptor() protoreflect.MessageDescriptor {
+	return m.mi.PBType.Descriptor()
+}
+func (m *messageState) New() protoreflect.Message {
+	return m.mi.PBType.New()
+}
+func (m *messageState) Interface() protoreflect.ProtoMessage {
+	return m.ProtoUnwrap().(protoreflect.ProtoMessage)
+}
+func (m *messageState) ProtoUnwrap() interface{} {
+	return m.pointer().AsIfaceOf(m.mi.GoType.Elem())
+}
+
+func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
+	m.mi.init()
+	for _, fi := range m.mi.fields {
+		if fi.has(m.pointer()) {
+			if !f(fi.fieldDesc, fi.get(m.pointer())) {
+				return
+			}
+		}
+	}
+	m.mi.extensionMap(m.pointer()).Range(f)
+}
+func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.has(m.pointer())
+	} else {
+		return m.mi.extensionMap(m.pointer()).Has(xt)
+	}
+}
+func (m *messageState) Clear(fd protoreflect.FieldDescriptor) {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		fi.clear(m.pointer())
+	} else {
+		m.mi.extensionMap(m.pointer()).Clear(xt)
+	}
+}
+func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.get(m.pointer())
+	} else {
+		return m.mi.extensionMap(m.pointer()).Get(xt)
+	}
+}
+func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		fi.set(m.pointer(), v)
+	} else {
+		m.mi.extensionMap(m.pointer()).Set(xt, v)
+	}
+}
+func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.mutable(m.pointer())
+	} else {
+		return m.mi.extensionMap(m.pointer()).Mutable(xt)
+	}
+}
+func (m *messageState) NewMessage(fd protoreflect.FieldDescriptor) protoreflect.Message {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.newMessage()
+	} else {
+		return xt.New().Message()
+	}
+}
+func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
+	m.mi.init()
+	if oi := m.mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
+		return od.Fields().ByNumber(oi.which(m.pointer()))
+	}
+	panic("invalid oneof descriptor")
+}
+func (m *messageState) GetUnknown() protoreflect.RawFields {
+	m.mi.init()
+	return m.mi.getUnknown(m.pointer())
+}
+func (m *messageState) SetUnknown(b protoreflect.RawFields) {
+	m.mi.init()
+	m.mi.setUnknown(m.pointer(), b)
+}
+
+func (m *messageReflectWrapper) Descriptor() protoreflect.MessageDescriptor {
+	return m.mi.PBType.Descriptor()
+}
+func (m *messageReflectWrapper) New() protoreflect.Message {
+	return m.mi.PBType.New()
+}
+func (m *messageReflectWrapper) Interface() protoreflect.ProtoMessage {
+	if m, ok := m.ProtoUnwrap().(protoreflect.ProtoMessage); ok {
+		return m
+	}
+	return (*messageIfaceWrapper)(m)
+}
+func (m *messageReflectWrapper) ProtoUnwrap() interface{} {
+	return m.pointer().AsIfaceOf(m.mi.GoType.Elem())
+}
+
+func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
+	m.mi.init()
+	for _, fi := range m.mi.fields {
+		if fi.has(m.pointer()) {
+			if !f(fi.fieldDesc, fi.get(m.pointer())) {
+				return
+			}
+		}
+	}
+	m.mi.extensionMap(m.pointer()).Range(f)
+}
+func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.has(m.pointer())
+	} else {
+		return m.mi.extensionMap(m.pointer()).Has(xt)
+	}
+}
+func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		fi.clear(m.pointer())
+	} else {
+		m.mi.extensionMap(m.pointer()).Clear(xt)
+	}
+}
+func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.get(m.pointer())
+	} else {
+		return m.mi.extensionMap(m.pointer()).Get(xt)
+	}
+}
+func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		fi.set(m.pointer(), v)
+	} else {
+		m.mi.extensionMap(m.pointer()).Set(xt, v)
+	}
+}
+func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.mutable(m.pointer())
+	} else {
+		return m.mi.extensionMap(m.pointer()).Mutable(xt)
+	}
+}
+func (m *messageReflectWrapper) NewMessage(fd protoreflect.FieldDescriptor) protoreflect.Message {
+	m.mi.init()
+	if fi, xt := m.mi.checkField(fd); fi != nil {
+		return fi.newMessage()
+	} else {
+		return xt.New().Message()
+	}
+}
+func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
+	m.mi.init()
+	if oi := m.mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
+		return od.Fields().ByNumber(oi.which(m.pointer()))
+	}
+	panic("invalid oneof descriptor")
+}
+func (m *messageReflectWrapper) GetUnknown() protoreflect.RawFields {
+	m.mi.init()
+	return m.mi.getUnknown(m.pointer())
+}
+func (m *messageReflectWrapper) SetUnknown(b protoreflect.RawFields) {
+	m.mi.init()
+	m.mi.setUnknown(m.pointer(), b)
+}