internal/fieldnum: generate field numbers for the google.protobuf package

Generate field numbers for the well-known types,
so that encoding/jsonpb can benefit from them as well.

This CL fixes internal/cmd/generate-protos, which was silently failing
because the modulePath was not properly initialized. We fix this by
moving it to the start of the init function.

Change-Id: I87637176f29218cffa512b4baa49f39dae924061
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/168497
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/cmd/protoc-gen-go/annotation_test.go b/cmd/protoc-gen-go/annotation_test.go
index 8f6adb4..1f38d5a 100644
--- a/cmd/protoc-gen-go/annotation_test.go
+++ b/cmd/protoc-gen-go/annotation_test.go
@@ -10,7 +10,7 @@
 	"testing"
 
 	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/v2/internal/descfield"
+	"github.com/golang/protobuf/v2/internal/fieldnum"
 	"github.com/golang/protobuf/v2/internal/scalar"
 
 	descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
@@ -36,19 +36,19 @@
 		path                 []int32
 	}{{
 		"type ", "AnnotationsTestEnum", " int32",
-		[]int32{descfield.FileDescriptorProto_EnumType, 0},
+		[]int32{fieldnum.FileDescriptorProto_EnumType, 0},
 	}, {
 		"\t", "AnnotationsTestEnum_ANNOTATIONS_TEST_ENUM_VALUE", " AnnotationsTestEnum = 0",
-		[]int32{descfield.FileDescriptorProto_EnumType, 0, descfield.EnumDescriptorProto_Value, 0},
+		[]int32{fieldnum.FileDescriptorProto_EnumType, 0, fieldnum.EnumDescriptorProto_Value, 0},
 	}, {
 		"type ", "AnnotationsTestMessage", " struct {",
-		[]int32{descfield.FileDescriptorProto_MessageType, 0},
+		[]int32{fieldnum.FileDescriptorProto_MessageType, 0},
 	}, {
 		"\t", "AnnotationsTestField", " ",
-		[]int32{descfield.FileDescriptorProto_MessageType, 0, descfield.DescriptorProto_Field, 0},
+		[]int32{fieldnum.FileDescriptorProto_MessageType, 0, fieldnum.DescriptorProto_Field, 0},
 	}, {
 		"func (m *AnnotationsTestMessage) ", "GetAnnotationsTestField", "() string {",
-		[]int32{descfield.FileDescriptorProto_MessageType, 0, descfield.DescriptorProto_Field, 0},
+		[]int32{fieldnum.FileDescriptorProto_MessageType, 0, fieldnum.DescriptorProto_Field, 0},
 	}} {
 		s := want.prefix + want.text + want.suffix
 		pos := bytes.Index(sourceFile, []byte(s))
diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go
index b3f7bcf..95e6611 100644
--- a/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/cmd/protoc-gen-go/internal_gengo/main.go
@@ -17,8 +17,8 @@
 	"unicode"
 	"unicode/utf8"
 
-	"github.com/golang/protobuf/v2/internal/descfield"
 	"github.com/golang/protobuf/v2/internal/encoding/tag"
+	"github.com/golang/protobuf/v2/internal/fieldnum"
 	"github.com/golang/protobuf/v2/proto"
 	"github.com/golang/protobuf/v2/protogen"
 	"github.com/golang/protobuf/v2/reflect/protoreflect"
@@ -115,7 +115,7 @@
 	g.P()
 	g.PrintLeadingComments(protogen.Location{
 		SourceFile: f.Proto.GetName(),
-		Path:       []int32{descfield.FileDescriptorProto_Package},
+		Path:       []int32{fieldnum.FileDescriptorProto_Package},
 	})
 	g.P()
 	g.P("package ", f.GoPackageName)
diff --git a/encoding/jsonpb/well_known_types.go b/encoding/jsonpb/well_known_types.go
index 1beb07e..a9efdd3 100644
--- a/encoding/jsonpb/well_known_types.go
+++ b/encoding/jsonpb/well_known_types.go
@@ -10,6 +10,7 @@
 	"time"
 
 	"github.com/golang/protobuf/v2/internal/errors"
+	"github.com/golang/protobuf/v2/internal/fieldnum"
 	"github.com/golang/protobuf/v2/proto"
 	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
 )
@@ -86,15 +87,12 @@
 	msgType := m.Type()
 	knownFields := m.KnownFields()
 
-	const typeNum = 1  // string type_url.
-	const valueNum = 2 // bytes value.
-
 	// Start writing the JSON object.
 	e.StartObject()
 	defer e.EndObject()
 
-	if !knownFields.Has(typeNum) {
-		if !knownFields.Has(valueNum) {
+	if !knownFields.Has(fieldnum.Any_TypeUrl) {
+		if !knownFields.Has(fieldnum.Any_Value) {
 			// If message is empty, marshal out empty JSON object.
 			return nil
 		} else {
@@ -103,8 +101,8 @@
 		}
 	}
 
-	typeVal := knownFields.Get(typeNum)
-	valueVal := knownFields.Get(valueNum)
+	typeVal := knownFields.Get(fieldnum.Any_TypeUrl)
+	valueVal := knownFields.Get(fieldnum.Any_Value)
 
 	// Marshal out @type field.
 	typeURL := typeVal.String()
@@ -151,7 +149,8 @@
 	fieldDescs := msgType.Fields()
 	knownFields := m.KnownFields()
 
-	const num = 1 // Field "value", type is dependent on msgType.
+	// The "value" field has the same field number for all wrapper types.
+	const num = fieldnum.BoolValue_Value
 	fd := fieldDescs.ByNumber(num)
 	val := knownFields.Get(num)
 	return e.marshalSingular(val, fd)
@@ -162,9 +161,8 @@
 	fieldDescs := msgType.Fields()
 	knownFields := m.KnownFields()
 
-	const num = 1 // map<string, Value> fields.
-	fd := fieldDescs.ByNumber(num)
-	val := knownFields.Get(num)
+	fd := fieldDescs.ByNumber(fieldnum.Struct_Fields)
+	val := knownFields.Get(fieldnum.Struct_Fields)
 	return e.marshalMap(val.Map(), fd)
 }
 
@@ -173,9 +171,8 @@
 	fieldDescs := msgType.Fields()
 	knownFields := m.KnownFields()
 
-	const num = 1 // repeated Value values.
-	fd := fieldDescs.ByNumber(num)
-	val := knownFields.Get(num)
+	fd := fieldDescs.ByNumber(fieldnum.ListValue_Values)
+	val := knownFields.Get(fieldnum.ListValue_Values)
 	return e.marshalList(val.List(), fd)
 }
 
@@ -216,11 +213,8 @@
 	msgType := m.Type()
 	knownFields := m.KnownFields()
 
-	const secsNum = 1  // int64 seconds.
-	const nanosNum = 2 // int32 nanos.
-
-	secsVal := knownFields.Get(secsNum)
-	nanosVal := knownFields.Get(nanosNum)
+	secsVal := knownFields.Get(fieldnum.Duration_Seconds)
+	nanosVal := knownFields.Get(fieldnum.Duration_Nanos)
 	secs := secsVal.Int()
 	nanos := nanosVal.Int()
 	if secs < -maxSecondsInDuration || secs > maxSecondsInDuration {
@@ -258,11 +252,8 @@
 	msgType := m.Type()
 	knownFields := m.KnownFields()
 
-	const secsNum = 1  // int64 seconds.
-	const nanosNum = 2 // int32 nanos.
-
-	secsVal := knownFields.Get(secsNum)
-	nanosVal := knownFields.Get(nanosNum)
+	secsVal := knownFields.Get(fieldnum.Timestamp_Seconds)
+	nanosVal := knownFields.Get(fieldnum.Timestamp_Nanos)
 	secs := secsVal.Int()
 	nanos := nanosVal.Int()
 	if secs < minTimestampSeconds || secs > maxTimestampSeconds {
@@ -287,8 +278,7 @@
 	knownFields := m.KnownFields()
 	name := msgType.FullName()
 
-	const num = 1 // repeated string paths.
-	val := knownFields.Get(num)
+	val := knownFields.Get(fieldnum.FieldMask_Paths)
 	list := val.List()
 	paths := make([]string, 0, list.Len())
 
diff --git a/internal/cmd/generate-protos/main.go b/internal/cmd/generate-protos/main.go
index c2bbac3..ec358e3 100644
--- a/internal/cmd/generate-protos/main.go
+++ b/internal/cmd/generate-protos/main.go
@@ -27,6 +27,18 @@
 )
 
 func init() {
+	// Determine repository root path.
+	out, err := exec.Command("git", "rev-parse", "--show-toplevel").CombinedOutput()
+	check(err)
+	repoRoot = strings.TrimSpace(string(out))
+
+	// Determine the module path.
+	cmd := exec.Command("go", "list", "-m", "-f", "{{.Path}}")
+	cmd.Dir = repoRoot
+	out, err = cmd.CombinedOutput()
+	check(err)
+	modulePath = strings.TrimSpace(string(out))
+
 	// When the environment variable RUN_AS_PROTOC_PLUGIN is set,
 	// we skip running main and instead act as a protoc plugin.
 	// This allows the binary to pass itself to protoc.
@@ -42,7 +54,7 @@
 						switch plugin {
 						case "go":
 							gengo.GenerateFile(gen, file)
-							generateDescriptorFields(gen, file)
+							generateFieldNumbers(gen, file)
 						case "gogrpc":
 							gengogrpc.GenerateFile(gen, file)
 						}
@@ -79,18 +91,6 @@
 		panic("protobuf source root is not set")
 	}
 
-	// Determine repository root path.
-	out, err := exec.Command("git", "rev-parse", "--show-toplevel").CombinedOutput()
-	check(err)
-	repoRoot = strings.TrimSpace(string(out))
-
-	// Determine the module path.
-	cmd := exec.Command("go", "list", "-m", "-f", "{{.Path}}")
-	cmd.Dir = repoRoot
-	out, err = cmd.CombinedOutput()
-	check(err)
-	modulePath = strings.TrimSpace(string(out))
-
 	generateLocalProtos()
 	generateRemoteProtos()
 }
@@ -208,18 +208,19 @@
 	check(err)
 }
 
-// generateDescriptorFields generates an internal package for descriptor.proto.
-func generateDescriptorFields(gen *protogen.Plugin, file *protogen.File) {
-	if file.Desc.Path() != "google/protobuf/descriptor.proto" {
+// generateFieldNumbers generates an internal package for descriptor.proto
+// and well-known types.
+func generateFieldNumbers(gen *protogen.Plugin, file *protogen.File) {
+	if file.Desc.Package() != "google.protobuf" {
 		return
 	}
 
-	importPath := modulePath + "/internal/descfield"
-	g := gen.NewGeneratedFile(importPath+"/field_gen.go", protogen.GoImportPath(importPath))
+	importPath := modulePath + "/internal/fieldnum"
+	base := strings.TrimSuffix(path.Base(file.Desc.Path()), ".proto")
+	g := gen.NewGeneratedFile(importPath+"/"+base+"_gen.go", protogen.GoImportPath(importPath))
 	for _, s := range generatedPreamble {
 		g.P(s)
 	}
-	g.P("// Package descfield contains constants for field numbers in descriptor.proto.")
 	g.P("package ", path.Base(importPath))
 	g.P("")
 
diff --git a/internal/fieldnum/any_gen.go b/internal/fieldnum/any_gen.go
new file mode 100644
index 0000000..7bab555
--- /dev/null
+++ b/internal/fieldnum/any_gen.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Any.
+const (
+	Any_TypeUrl = 1 // optional string
+	Any_Value   = 2 // optional bytes
+)
diff --git a/internal/fieldnum/api_gen.go b/internal/fieldnum/api_gen.go
new file mode 100644
index 0000000..6014c86
--- /dev/null
+++ b/internal/fieldnum/api_gen.go
@@ -0,0 +1,35 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Api.
+const (
+	Api_Name          = 1 // optional string
+	Api_Methods       = 2 // repeated google.protobuf.Method
+	Api_Options       = 3 // repeated google.protobuf.Option
+	Api_Version       = 4 // optional string
+	Api_SourceContext = 5 // optional google.protobuf.SourceContext
+	Api_Mixins        = 6 // repeated google.protobuf.Mixin
+	Api_Syntax        = 7 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.Method.
+const (
+	Method_Name              = 1 // optional string
+	Method_RequestTypeUrl    = 2 // optional string
+	Method_RequestStreaming  = 3 // optional bool
+	Method_ResponseTypeUrl   = 4 // optional string
+	Method_ResponseStreaming = 5 // optional bool
+	Method_Options           = 6 // repeated google.protobuf.Option
+	Method_Syntax            = 7 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.Mixin.
+const (
+	Mixin_Name = 1 // optional string
+	Mixin_Root = 2 // optional string
+)
diff --git a/internal/descfield/field_gen.go b/internal/fieldnum/descriptor_gen.go
similarity index 98%
rename from internal/descfield/field_gen.go
rename to internal/fieldnum/descriptor_gen.go
index 0bc9f59..ab6753d 100644
--- a/internal/descfield/field_gen.go
+++ b/internal/fieldnum/descriptor_gen.go
@@ -4,8 +4,7 @@
 
 // Code generated by generate-protos. DO NOT EDIT.
 
-// Package descfield contains constants for field numbers in descriptor.proto.
-package descfield
+package fieldnum
 
 // Field numbers for google.protobuf.FileDescriptorSet.
 const (
diff --git a/internal/fieldnum/doc.go b/internal/fieldnum/doc.go
new file mode 100644
index 0000000..e597885
--- /dev/null
+++ b/internal/fieldnum/doc.go
@@ -0,0 +1,7 @@
+// 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 fieldnum contains constants for field numbers of fields in messages
+// declared in descriptor.proto and any of the well-known types.
+package fieldnum
diff --git a/internal/fieldnum/duration_gen.go b/internal/fieldnum/duration_gen.go
new file mode 100644
index 0000000..25b9dd5
--- /dev/null
+++ b/internal/fieldnum/duration_gen.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Duration.
+const (
+	Duration_Seconds = 1 // optional int64
+	Duration_Nanos   = 2 // optional int32
+)
diff --git a/internal/fieldnum/empty_gen.go b/internal/fieldnum/empty_gen.go
new file mode 100644
index 0000000..8dca214
--- /dev/null
+++ b/internal/fieldnum/empty_gen.go
@@ -0,0 +1,10 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Empty.
+const ()
diff --git a/internal/fieldnum/field_mask_gen.go b/internal/fieldnum/field_mask_gen.go
new file mode 100644
index 0000000..10c724a
--- /dev/null
+++ b/internal/fieldnum/field_mask_gen.go
@@ -0,0 +1,12 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.FieldMask.
+const (
+	FieldMask_Paths = 1 // repeated string
+)
diff --git a/internal/fieldnum/source_context_gen.go b/internal/fieldnum/source_context_gen.go
new file mode 100644
index 0000000..428c79b
--- /dev/null
+++ b/internal/fieldnum/source_context_gen.go
@@ -0,0 +1,12 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.SourceContext.
+const (
+	SourceContext_FileName = 1 // optional string
+)
diff --git a/internal/fieldnum/struct_gen.go b/internal/fieldnum/struct_gen.go
new file mode 100644
index 0000000..7db1a75
--- /dev/null
+++ b/internal/fieldnum/struct_gen.go
@@ -0,0 +1,33 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Struct.
+const (
+	Struct_Fields = 1 // repeated google.protobuf.Struct.FieldsEntry
+)
+
+// Field numbers for google.protobuf.Struct.FieldsEntry.
+const (
+	Struct_FieldsEntry_Key   = 1 // optional string
+	Struct_FieldsEntry_Value = 2 // optional google.protobuf.Value
+)
+
+// Field numbers for google.protobuf.Value.
+const (
+	Value_NullValue   = 1 // optional google.protobuf.NullValue
+	Value_NumberValue = 2 // optional double
+	Value_StringValue = 3 // optional string
+	Value_BoolValue   = 4 // optional bool
+	Value_StructValue = 5 // optional google.protobuf.Struct
+	Value_ListValue   = 6 // optional google.protobuf.ListValue
+)
+
+// Field numbers for google.protobuf.ListValue.
+const (
+	ListValue_Values = 1 // repeated google.protobuf.Value
+)
diff --git a/internal/fieldnum/timestamp_gen.go b/internal/fieldnum/timestamp_gen.go
new file mode 100644
index 0000000..a808185
--- /dev/null
+++ b/internal/fieldnum/timestamp_gen.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Timestamp.
+const (
+	Timestamp_Seconds = 1 // optional int64
+	Timestamp_Nanos   = 2 // optional int32
+)
diff --git a/internal/fieldnum/type_gen.go b/internal/fieldnum/type_gen.go
new file mode 100644
index 0000000..ce85d04
--- /dev/null
+++ b/internal/fieldnum/type_gen.go
@@ -0,0 +1,53 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.Type.
+const (
+	Type_Name          = 1 // optional string
+	Type_Fields        = 2 // repeated google.protobuf.Field
+	Type_Oneofs        = 3 // repeated string
+	Type_Options       = 4 // repeated google.protobuf.Option
+	Type_SourceContext = 5 // optional google.protobuf.SourceContext
+	Type_Syntax        = 6 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.Field.
+const (
+	Field_Kind         = 1  // optional google.protobuf.Field.Kind
+	Field_Cardinality  = 2  // optional google.protobuf.Field.Cardinality
+	Field_Number       = 3  // optional int32
+	Field_Name         = 4  // optional string
+	Field_TypeUrl      = 6  // optional string
+	Field_OneofIndex   = 7  // optional int32
+	Field_Packed       = 8  // optional bool
+	Field_Options      = 9  // repeated google.protobuf.Option
+	Field_JsonName     = 10 // optional string
+	Field_DefaultValue = 11 // optional string
+)
+
+// Field numbers for google.protobuf.Enum.
+const (
+	Enum_Name          = 1 // optional string
+	Enum_Enumvalue     = 2 // repeated google.protobuf.EnumValue
+	Enum_Options       = 3 // repeated google.protobuf.Option
+	Enum_SourceContext = 4 // optional google.protobuf.SourceContext
+	Enum_Syntax        = 5 // optional google.protobuf.Syntax
+)
+
+// Field numbers for google.protobuf.EnumValue.
+const (
+	EnumValue_Name    = 1 // optional string
+	EnumValue_Number  = 2 // optional int32
+	EnumValue_Options = 3 // repeated google.protobuf.Option
+)
+
+// Field numbers for google.protobuf.Option.
+const (
+	Option_Name  = 1 // optional string
+	Option_Value = 2 // optional google.protobuf.Any
+)
diff --git a/internal/fieldnum/wrappers_gen.go b/internal/fieldnum/wrappers_gen.go
new file mode 100644
index 0000000..6882713
--- /dev/null
+++ b/internal/fieldnum/wrappers_gen.go
@@ -0,0 +1,52 @@
+// 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.
+
+// Code generated by generate-protos. DO NOT EDIT.
+
+package fieldnum
+
+// Field numbers for google.protobuf.DoubleValue.
+const (
+	DoubleValue_Value = 1 // optional double
+)
+
+// Field numbers for google.protobuf.FloatValue.
+const (
+	FloatValue_Value = 1 // optional float
+)
+
+// Field numbers for google.protobuf.Int64Value.
+const (
+	Int64Value_Value = 1 // optional int64
+)
+
+// Field numbers for google.protobuf.UInt64Value.
+const (
+	UInt64Value_Value = 1 // optional uint64
+)
+
+// Field numbers for google.protobuf.Int32Value.
+const (
+	Int32Value_Value = 1 // optional int32
+)
+
+// Field numbers for google.protobuf.UInt32Value.
+const (
+	UInt32Value_Value = 1 // optional uint32
+)
+
+// Field numbers for google.protobuf.BoolValue.
+const (
+	BoolValue_Value = 1 // optional bool
+)
+
+// Field numbers for google.protobuf.StringValue.
+const (
+	StringValue_Value = 1 // optional string
+)
+
+// Field numbers for google.protobuf.BytesValue.
+const (
+	BytesValue_Value = 1 // optional bytes
+)
diff --git a/internal/fileinit/desc_init.go b/internal/fileinit/desc_init.go
index bd706fc..7d14998 100644
--- a/internal/fileinit/desc_init.go
+++ b/internal/fileinit/desc_init.go
@@ -5,8 +5,8 @@
 package fileinit
 
 import (
-	descfield "github.com/golang/protobuf/v2/internal/descfield"
 	wire "github.com/golang/protobuf/v2/internal/encoding/wire"
+	fieldnum "github.com/golang/protobuf/v2/internal/fieldnum"
 	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
 )
 
@@ -89,36 +89,36 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.FileDescriptorProto_Name:
+			case fieldnum.FileDescriptorProto_Name:
 				fd.path = nb.MakeString(v)
-			case descfield.FileDescriptorProto_Package:
+			case fieldnum.FileDescriptorProto_Package:
 				fd.protoPackage = pref.FullName(nb.MakeString(v))
-			case descfield.FileDescriptorProto_EnumType:
-				if prevField != descfield.FileDescriptorProto_EnumType {
+			case fieldnum.FileDescriptorProto_EnumType:
+				if prevField != fieldnum.FileDescriptorProto_EnumType {
 					if numEnums > 0 {
 						panic("non-contiguous repeated field")
 					}
 					posEnums = len(b0) - len(b) - n - m
 				}
 				numEnums++
-			case descfield.FileDescriptorProto_MessageType:
-				if prevField != descfield.FileDescriptorProto_MessageType {
+			case fieldnum.FileDescriptorProto_MessageType:
+				if prevField != fieldnum.FileDescriptorProto_MessageType {
 					if numMessages > 0 {
 						panic("non-contiguous repeated field")
 					}
 					posMessages = len(b0) - len(b) - n - m
 				}
 				numMessages++
-			case descfield.FileDescriptorProto_Extension:
-				if prevField != descfield.FileDescriptorProto_Extension {
+			case fieldnum.FileDescriptorProto_Extension:
+				if prevField != fieldnum.FileDescriptorProto_Extension {
 					if numExtensions > 0 {
 						panic("non-contiguous repeated field")
 					}
 					posExtensions = len(b0) - len(b) - n - m
 				}
 				numExtensions++
-			case descfield.FileDescriptorProto_Service:
-				if prevField != descfield.FileDescriptorProto_Service {
+			case fieldnum.FileDescriptorProto_Service:
+				if prevField != fieldnum.FileDescriptorProto_Service {
 					if numServices > 0 {
 						panic("non-contiguous repeated field")
 					}
@@ -200,7 +200,7 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.EnumDescriptorProto_Name:
+			case fieldnum.EnumDescriptorProto_Name:
 				ed.fullName = nb.AppendFullName(pd.FullName(), v)
 			}
 		default:
@@ -227,26 +227,26 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.DescriptorProto_Name:
+			case fieldnum.DescriptorProto_Name:
 				md.fullName = nb.AppendFullName(pd.FullName(), v)
-			case descfield.DescriptorProto_EnumType:
-				if prevField != descfield.DescriptorProto_EnumType {
+			case fieldnum.DescriptorProto_EnumType:
+				if prevField != fieldnum.DescriptorProto_EnumType {
 					if numEnums > 0 {
 						panic("non-contiguous repeated field")
 					}
 					posEnums = len(b0) - len(b) - n - m
 				}
 				numEnums++
-			case descfield.DescriptorProto_NestedType:
-				if prevField != descfield.DescriptorProto_NestedType {
+			case fieldnum.DescriptorProto_NestedType:
+				if prevField != fieldnum.DescriptorProto_NestedType {
 					if numMessages > 0 {
 						panic("non-contiguous repeated field")
 					}
 					posMessages = len(b0) - len(b) - n - m
 				}
 				numMessages++
-			case descfield.DescriptorProto_Extension:
-				if prevField != descfield.DescriptorProto_Extension {
+			case fieldnum.DescriptorProto_Extension:
+				if prevField != fieldnum.DescriptorProto_Extension {
 					if numExtensions > 0 {
 						panic("non-contiguous repeated field")
 					}
@@ -316,14 +316,14 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldDescriptorProto_Number:
+			case fieldnum.FieldDescriptorProto_Number:
 				xd.number = pref.FieldNumber(v)
 			}
 		case wire.BytesType:
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldDescriptorProto_Name:
+			case fieldnum.FieldDescriptorProto_Name:
 				xd.fullName = nb.AppendFullName(pd.FullName(), v)
 			}
 		default:
@@ -346,7 +346,7 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.ServiceDescriptorProto_Name:
+			case fieldnum.ServiceDescriptorProto_Name:
 				sd.fullName = nb.AppendFullName(pd.FullName(), v)
 			}
 		default:
diff --git a/internal/fileinit/desc_lazy.go b/internal/fileinit/desc_lazy.go
index ffcad72..4eef546 100644
--- a/internal/fileinit/desc_lazy.go
+++ b/internal/fileinit/desc_lazy.go
@@ -9,9 +9,9 @@
 	"fmt"
 	"reflect"
 
-	descfield "github.com/golang/protobuf/v2/internal/descfield"
 	defval "github.com/golang/protobuf/v2/internal/encoding/defval"
 	wire "github.com/golang/protobuf/v2/internal/encoding/wire"
+	fieldnum "github.com/golang/protobuf/v2/internal/fieldnum"
 	pimpl "github.com/golang/protobuf/v2/internal/impl"
 	ptype "github.com/golang/protobuf/v2/internal/prototype"
 	pvalue "github.com/golang/protobuf/v2/internal/value"
@@ -345,16 +345,16 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.FileDescriptorProto_PublicDependency:
+			case fieldnum.FileDescriptorProto_PublicDependency:
 				fd.lazy.imports[v].IsPublic = true
-			case descfield.FileDescriptorProto_WeakDependency:
+			case fieldnum.FileDescriptorProto_WeakDependency:
 				fd.lazy.imports[v].IsWeak = true
 			}
 		case wire.BytesType:
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.FileDescriptorProto_Syntax:
+			case fieldnum.FileDescriptorProto_Syntax:
 				hasSyntax = true
 				switch string(v) {
 				case "proto2":
@@ -364,23 +364,23 @@
 				default:
 					panic("invalid syntax")
 				}
-			case descfield.FileDescriptorProto_Dependency:
+			case fieldnum.FileDescriptorProto_Dependency:
 				fd.lazy.imports = append(fd.lazy.imports, pref.FileImport{
 					FileDescriptor: ptype.PlaceholderFile(nb.MakeString(v), ""),
 				})
-			case descfield.FileDescriptorProto_EnumType:
+			case fieldnum.FileDescriptorProto_EnumType:
 				fd.enums.list[enumIdx].unmarshalFull(v, nb)
 				enumIdx++
-			case descfield.FileDescriptorProto_MessageType:
+			case fieldnum.FileDescriptorProto_MessageType:
 				fd.messages.list[messageIdx].unmarshalFull(v, nb)
 				messageIdx++
-			case descfield.FileDescriptorProto_Extension:
+			case fieldnum.FileDescriptorProto_Extension:
 				fd.extensions.list[extensionIdx].unmarshalFull(v, nb)
 				extensionIdx++
-			case descfield.FileDescriptorProto_Service:
+			case fieldnum.FileDescriptorProto_Service:
 				fd.services.list[serviceIdx].unmarshalFull(v, nb)
 				serviceIdx++
-			case descfield.FileDescriptorProto_Options:
+			case fieldnum.FileDescriptorProto_Options:
 				fd.lazy.options = append(fd.lazy.options, v...)
 			}
 		default:
@@ -406,13 +406,13 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.EnumDescriptorProto_Value:
+			case fieldnum.EnumDescriptorProto_Value:
 				rawValues = append(rawValues, v)
-			case descfield.EnumDescriptorProto_ReservedName:
+			case fieldnum.EnumDescriptorProto_ReservedName:
 				ed.lazy.resvNames.list = append(ed.lazy.resvNames.list, pref.Name(nb.MakeString(v)))
-			case descfield.EnumDescriptorProto_ReservedRange:
+			case fieldnum.EnumDescriptorProto_ReservedRange:
 				ed.lazy.resvRanges.list = append(ed.lazy.resvRanges.list, unmarshalEnumReservedRange(v))
-			case descfield.EnumDescriptorProto_Options:
+			case fieldnum.EnumDescriptorProto_Options:
 				ed.lazy.options = append(ed.lazy.options, v...)
 			}
 		default:
@@ -440,9 +440,9 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.EnumDescriptorProto_EnumReservedRange_Start:
+			case fieldnum.EnumDescriptorProto_EnumReservedRange_Start:
 				r[0] = pref.EnumNumber(v)
-			case descfield.EnumDescriptorProto_EnumReservedRange_End:
+			case fieldnum.EnumDescriptorProto_EnumReservedRange_End:
 				r[1] = pref.EnumNumber(v)
 			}
 		default:
@@ -466,16 +466,16 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.EnumValueDescriptorProto_Number:
+			case fieldnum.EnumValueDescriptorProto_Number:
 				vd.number = pref.EnumNumber(v)
 			}
 		case wire.BytesType:
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.EnumValueDescriptorProto_Name:
+			case fieldnum.EnumValueDescriptorProto_Name:
 				vd.fullName = nb.AppendFullName(pd.FullName(), v)
-			case descfield.EnumValueDescriptorProto_Options:
+			case fieldnum.EnumValueDescriptorProto_Options:
 				vd.options = append(vd.options, v...)
 			}
 		default:
@@ -499,28 +499,28 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.DescriptorProto_Field:
+			case fieldnum.DescriptorProto_Field:
 				rawFields = append(rawFields, v)
-			case descfield.DescriptorProto_OneofDecl:
+			case fieldnum.DescriptorProto_OneofDecl:
 				rawOneofs = append(rawOneofs, v)
-			case descfield.DescriptorProto_ReservedName:
+			case fieldnum.DescriptorProto_ReservedName:
 				md.lazy.resvNames.list = append(md.lazy.resvNames.list, pref.Name(nb.MakeString(v)))
-			case descfield.DescriptorProto_ReservedRange:
+			case fieldnum.DescriptorProto_ReservedRange:
 				md.lazy.resvRanges.list = append(md.lazy.resvRanges.list, unmarshalMessageReservedRange(v))
-			case descfield.DescriptorProto_ExtensionRange:
+			case fieldnum.DescriptorProto_ExtensionRange:
 				r, opts := unmarshalMessageExtensionRange(v)
 				md.lazy.extRanges.list = append(md.lazy.extRanges.list, r)
 				md.lazy.extRangeOptions = append(md.lazy.extRangeOptions, opts)
-			case descfield.DescriptorProto_EnumType:
+			case fieldnum.DescriptorProto_EnumType:
 				md.enums.list[enumIdx].unmarshalFull(v, nb)
 				enumIdx++
-			case descfield.DescriptorProto_NestedType:
+			case fieldnum.DescriptorProto_NestedType:
 				md.messages.list[messageIdx].unmarshalFull(v, nb)
 				messageIdx++
-			case descfield.DescriptorProto_Extension:
+			case fieldnum.DescriptorProto_Extension:
 				md.extensions.list[extensionIdx].unmarshalFull(v, nb)
 				extensionIdx++
-			case descfield.DescriptorProto_Options:
+			case fieldnum.DescriptorProto_Options:
 				md.unmarshalOptions(v)
 			}
 		default:
@@ -558,9 +558,9 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.MessageOptions_MapEntry:
+			case fieldnum.MessageOptions_MapEntry:
 				md.lazy.isMapEntry = wire.DecodeBool(v)
-			case descfield.MessageOptions_MessageSetWireFormat:
+			case fieldnum.MessageOptions_MessageSetWireFormat:
 				md.lazy.isMessageSet = wire.DecodeBool(v)
 			}
 		default:
@@ -579,9 +579,9 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.DescriptorProto_ReservedRange_Start:
+			case fieldnum.DescriptorProto_ReservedRange_Start:
 				r[0] = pref.FieldNumber(v)
-			case descfield.DescriptorProto_ReservedRange_End:
+			case fieldnum.DescriptorProto_ReservedRange_End:
 				r[1] = pref.FieldNumber(v)
 			}
 		default:
@@ -601,16 +601,16 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.DescriptorProto_ExtensionRange_Start:
+			case fieldnum.DescriptorProto_ExtensionRange_Start:
 				r[0] = pref.FieldNumber(v)
-			case descfield.DescriptorProto_ExtensionRange_End:
+			case fieldnum.DescriptorProto_ExtensionRange_End:
 				r[1] = pref.FieldNumber(v)
 			}
 		case wire.BytesType:
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.DescriptorProto_ExtensionRange_Options:
+			case fieldnum.DescriptorProto_ExtensionRange_Options:
 				opts = append(opts, v...)
 			}
 		default:
@@ -636,13 +636,13 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldDescriptorProto_Number:
+			case fieldnum.FieldDescriptorProto_Number:
 				fd.number = pref.FieldNumber(v)
-			case descfield.FieldDescriptorProto_Label:
+			case fieldnum.FieldDescriptorProto_Label:
 				fd.cardinality = pref.Cardinality(v)
-			case descfield.FieldDescriptorProto_Type:
+			case fieldnum.FieldDescriptorProto_Type:
 				fd.kind = pref.Kind(v)
-			case descfield.FieldDescriptorProto_OneofIndex:
+			case fieldnum.FieldDescriptorProto_OneofIndex:
 				// In messageDesc.UnmarshalFull, we allocate slices for both
 				// the field and oneof descriptors before unmarshaling either
 				// of them. This ensures pointers to slice elements are stable.
@@ -657,17 +657,17 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldDescriptorProto_Name:
+			case fieldnum.FieldDescriptorProto_Name:
 				fd.fullName = nb.AppendFullName(pd.FullName(), v)
-			case descfield.FieldDescriptorProto_JsonName:
+			case fieldnum.FieldDescriptorProto_JsonName:
 				fd.hasJSONName = true
 				fd.jsonName = nb.MakeString(v)
-			case descfield.FieldDescriptorProto_DefaultValue:
+			case fieldnum.FieldDescriptorProto_DefaultValue:
 				fd.defVal.has = true
 				rawDefVal = v
-			case descfield.FieldDescriptorProto_TypeName:
+			case fieldnum.FieldDescriptorProto_TypeName:
 				rawTypeName = v
-			case descfield.FieldDescriptorProto_Options:
+			case fieldnum.FieldDescriptorProto_Options:
 				fd.unmarshalOptions(v)
 			}
 		default:
@@ -706,10 +706,10 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldOptions_Packed:
+			case fieldnum.FieldOptions_Packed:
 				fd.hasPacked = true
 				fd.isPacked = wire.DecodeBool(v)
-			case descfield.FieldOptions_Weak:
+			case fieldnum.FieldOptions_Weak:
 				fd.isWeak = wire.DecodeBool(v)
 			}
 		default:
@@ -732,9 +732,9 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.OneofDescriptorProto_Name:
+			case fieldnum.OneofDescriptorProto_Name:
 				od.fullName = nb.AppendFullName(pd.FullName(), v)
-			case descfield.OneofDescriptorProto_Options:
+			case fieldnum.OneofDescriptorProto_Options:
 				od.options = append(od.options, v...)
 			}
 		default:
@@ -757,22 +757,22 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldDescriptorProto_Label:
+			case fieldnum.FieldDescriptorProto_Label:
 				xd.lazy.cardinality = pref.Cardinality(v)
-			case descfield.FieldDescriptorProto_Type:
+			case fieldnum.FieldDescriptorProto_Type:
 				xd.lazy.kind = pref.Kind(v)
 			}
 		case wire.BytesType:
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldDescriptorProto_JsonName:
+			case fieldnum.FieldDescriptorProto_JsonName:
 				xd.lazy.hasJSONName = true
 				xd.lazy.jsonName = nb.MakeString(v)
-			case descfield.FieldDescriptorProto_DefaultValue:
+			case fieldnum.FieldDescriptorProto_DefaultValue:
 				xd.lazy.defVal.has = true
 				rawDefVal = v
-			case descfield.FieldDescriptorProto_Options:
+			case fieldnum.FieldDescriptorProto_Options:
 				xd.unmarshalOptions(v)
 			}
 		default:
@@ -802,7 +802,7 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.FieldOptions_Packed:
+			case fieldnum.FieldOptions_Packed:
 				xd.lazy.isPacked = wire.DecodeBool(v)
 			}
 		default:
@@ -823,9 +823,9 @@
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.ServiceDescriptorProto_Method:
+			case fieldnum.ServiceDescriptorProto_Method:
 				rawMethods = append(rawMethods, v)
-			case descfield.ServiceDescriptorProto_Options:
+			case fieldnum.ServiceDescriptorProto_Options:
 				sd.lazy.options = append(sd.lazy.options, v...)
 			}
 		default:
@@ -857,18 +857,18 @@
 			v, m := wire.ConsumeVarint(b)
 			b = b[m:]
 			switch num {
-			case descfield.MethodDescriptorProto_ClientStreaming:
+			case fieldnum.MethodDescriptorProto_ClientStreaming:
 				md.isStreamingClient = wire.DecodeBool(v)
-			case descfield.MethodDescriptorProto_ServerStreaming:
+			case fieldnum.MethodDescriptorProto_ServerStreaming:
 				md.isStreamingServer = wire.DecodeBool(v)
 			}
 		case wire.BytesType:
 			v, m := wire.ConsumeBytes(b)
 			b = b[m:]
 			switch num {
-			case descfield.MethodDescriptorProto_Name:
+			case fieldnum.MethodDescriptorProto_Name:
 				md.fullName = nb.AppendFullName(pd.FullName(), v)
-			case descfield.MethodDescriptorProto_Options:
+			case fieldnum.MethodDescriptorProto_Options:
 				md.options = append(md.options, v...)
 			}
 		default:
diff --git a/protogen/protogen.go b/protogen/protogen.go
index 1aade1b..9dd48fc 100644
--- a/protogen/protogen.go
+++ b/protogen/protogen.go
@@ -29,7 +29,7 @@
 	"strings"
 
 	"github.com/golang/protobuf/v2/encoding/textpb"
-	"github.com/golang/protobuf/v2/internal/descfield"
+	"github.com/golang/protobuf/v2/internal/fieldnum"
 	"github.com/golang/protobuf/v2/internal/scalar"
 	"github.com/golang/protobuf/v2/proto"
 	"github.com/golang/protobuf/v2/reflect/protodesc"
@@ -520,9 +520,9 @@
 func newMessage(gen *Plugin, f *File, parent *Message, desc protoreflect.MessageDescriptor) *Message {
 	var loc Location
 	if parent != nil {
-		loc = parent.Location.appendPath(descfield.DescriptorProto_NestedType, int32(desc.Index()))
+		loc = parent.Location.appendPath(fieldnum.DescriptorProto_NestedType, int32(desc.Index()))
 	} else {
-		loc = f.location(descfield.FileDescriptorProto_MessageType, int32(desc.Index()))
+		loc = f.location(fieldnum.FileDescriptorProto_MessageType, int32(desc.Index()))
 	}
 	message := &Message{
 		Desc:     desc,
@@ -638,11 +638,11 @@
 	var loc Location
 	switch {
 	case desc.ExtendedType() != nil && message == nil:
-		loc = f.location(descfield.FileDescriptorProto_Extension, int32(desc.Index()))
+		loc = f.location(fieldnum.FileDescriptorProto_Extension, int32(desc.Index()))
 	case desc.ExtendedType() != nil && message != nil:
-		loc = message.Location.appendPath(descfield.DescriptorProto_Extension, int32(desc.Index()))
+		loc = message.Location.appendPath(fieldnum.DescriptorProto_Extension, int32(desc.Index()))
 	default:
-		loc = message.Location.appendPath(descfield.DescriptorProto_Field, int32(desc.Index()))
+		loc = message.Location.appendPath(fieldnum.DescriptorProto_Field, int32(desc.Index()))
 	}
 	field := &Field{
 		Desc:          desc,
@@ -703,7 +703,7 @@
 		Desc:          desc,
 		ParentMessage: message,
 		GoName:        camelCase(string(desc.Name())),
-		Location:      message.Location.appendPath(descfield.DescriptorProto_OneofDecl, int32(desc.Index())),
+		Location:      message.Location.appendPath(fieldnum.DescriptorProto_OneofDecl, int32(desc.Index())),
 	}
 }
 
@@ -725,9 +725,9 @@
 func newEnum(gen *Plugin, f *File, parent *Message, desc protoreflect.EnumDescriptor) *Enum {
 	var loc Location
 	if parent != nil {
-		loc = parent.Location.appendPath(descfield.DescriptorProto_EnumType, int32(desc.Index()))
+		loc = parent.Location.appendPath(fieldnum.DescriptorProto_EnumType, int32(desc.Index()))
 	} else {
-		loc = f.location(descfield.FileDescriptorProto_EnumType, int32(desc.Index()))
+		loc = f.location(fieldnum.FileDescriptorProto_EnumType, int32(desc.Index()))
 	}
 	enum := &Enum{
 		Desc:     desc,
@@ -762,7 +762,7 @@
 	return &EnumValue{
 		Desc:     desc,
 		GoIdent:  f.GoImportPath.Ident(name),
-		Location: enum.Location.appendPath(descfield.EnumDescriptorProto_Value, int32(desc.Index())),
+		Location: enum.Location.appendPath(fieldnum.EnumDescriptorProto_Value, int32(desc.Index())),
 	}
 }
 
@@ -779,7 +779,7 @@
 	service := &Service{
 		Desc:     desc,
 		GoName:   camelCase(string(desc.Name())),
-		Location: f.location(descfield.FileDescriptorProto_Service, int32(desc.Index())),
+		Location: f.location(fieldnum.FileDescriptorProto_Service, int32(desc.Index())),
 	}
 	for i, mdescs := 0, desc.Methods(); i < mdescs.Len(); i++ {
 		service.Methods = append(service.Methods, newMethod(gen, f, service, mdescs.Get(i)))
@@ -803,7 +803,7 @@
 		Desc:          desc,
 		GoName:        camelCase(string(desc.Name())),
 		ParentService: service,
-		Location:      service.Location.appendPath(descfield.ServiceDescriptorProto_Method, int32(desc.Index())),
+		Location:      service.Location.appendPath(fieldnum.ServiceDescriptorProto_Method, int32(desc.Index())),
 	}
 	return method
 }