internal/filedesc: use jsonName.Init method over JSONName constructor

The JSONName constructor returns a struct value which shallow copies
a sync.Once within it; this is a dubious pattern.
Instead, add a jsonName.Init method to initialize the value.

Change-Id: I190a7239b1b62a8041ee7e4e09c0fe37b64ff623
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/213237
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/encoding/tag/tag.go b/internal/encoding/tag/tag.go
index a0d9db8..16c02d7 100644
--- a/internal/encoding/tag/tag.go
+++ b/internal/encoding/tag/tag.go
@@ -104,7 +104,7 @@
 		case strings.HasPrefix(s, "json="):
 			jsonName := s[len("json="):]
 			if jsonName != strs.JSONCamelCase(string(f.L0.FullName.Name())) {
-				f.L1.JSONName = fdesc.JSONName(jsonName)
+				f.L1.JSONName.Init(jsonName)
 			}
 		case s == "packed":
 			f.L1.HasPacked = true
diff --git a/internal/filedesc/desc.go b/internal/filedesc/desc.go
index 8185758..a9fe07c 100644
--- a/internal/filedesc/desc.go
+++ b/internal/filedesc/desc.go
@@ -490,16 +490,18 @@
 func (d *Base) IsPlaceholder() bool                 { return false }
 func (d *Base) ProtoInternal(pragma.DoNotImplement) {}
 
-func JSONName(s string) jsonName {
-	return jsonName{has: true, name: s}
-}
-
 type jsonName struct {
 	has  bool
 	once sync.Once
 	name string
 }
 
+// Init initializes the name. It is exported for use by other internal packages.
+func (js *jsonName) Init(s string) {
+	js.has = true
+	js.name = s
+}
+
 func (js *jsonName) get(fd pref.FieldDescriptor) string {
 	if !js.has {
 		js.once.Do(func() {
diff --git a/internal/filedesc/desc_lazy.go b/internal/filedesc/desc_lazy.go
index 309d739..c43b3e2 100644
--- a/internal/filedesc/desc_lazy.go
+++ b/internal/filedesc/desc_lazy.go
@@ -449,7 +449,7 @@
 			case fieldnum.FieldDescriptorProto_Name:
 				fd.L0.FullName = appendFullName(sb, pd.FullName(), v)
 			case fieldnum.FieldDescriptorProto_JsonName:
-				fd.L1.JSONName = JSONName(sb.MakeString(v))
+				fd.L1.JSONName.Init(sb.MakeString(v))
 			case fieldnum.FieldDescriptorProto_DefaultValue:
 				fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages
 			case fieldnum.FieldDescriptorProto_TypeName:
@@ -542,7 +542,7 @@
 			b = b[m:]
 			switch num {
 			case fieldnum.FieldDescriptorProto_JsonName:
-				xd.L2.JSONName = JSONName(sb.MakeString(v))
+				xd.L2.JSONName.Init(sb.MakeString(v))
 			case fieldnum.FieldDescriptorProto_DefaultValue:
 				xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions
 			case fieldnum.FieldDescriptorProto_TypeName:
diff --git a/reflect/protodesc/desc_init.go b/reflect/protodesc/desc_init.go
index 6f689b1..ef2d071 100644
--- a/reflect/protodesc/desc_init.go
+++ b/reflect/protodesc/desc_init.go
@@ -133,7 +133,7 @@
 			f.L1.Kind = protoreflect.Kind(fd.GetType())
 		}
 		if fd.JsonName != nil {
-			f.L1.JSONName = filedesc.JSONName(fd.GetJsonName())
+			f.L1.JSONName.Init(fd.GetJsonName())
 		}
 	}
 	return fs, nil
@@ -173,7 +173,7 @@
 			x.L1.Kind = protoreflect.Kind(xd.GetType())
 		}
 		if xd.JsonName != nil {
-			x.L2.JSONName = filedesc.JSONName(xd.GetJsonName())
+			x.L2.JSONName.Init(xd.GetJsonName())
 		}
 	}
 	return xs, nil