internal/impl: improve extension fast path performance

Stash fast-path information for extensions on the ExtensionInfo. In
the usual case where an ExtensionType's underlying implementation is
an *ExtensionInfo, fetching the fast-path information becomes a type
assertion rather than a mutex-guarded map access.

Maintain a global sync.Map for the case where an ExtensionType isn't an
*ExtensionInfo.

Substantially improves performance for fast-path operations on
extensions:

Encode/MessageSet_type_id_before_message_content-12      267ns ± 1%   185ns ± 1%  -30.44%  (p=0.001 n=7+7)
Encode/basic_scalar_types_(*test.TestAllExtensions)-12  1.94µs ± 1%  0.40µs ± 1%  -79.32%  (p=0.000 n=8+7)

Change-Id: If048b521deb3665a090ea3d0a178c61691d4201e
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/210540
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/internal/impl/isinit.go b/internal/impl/isinit.go
index 3fd3674..d3a01bc 100644
--- a/internal/impl/isinit.go
+++ b/internal/impl/isinit.go
@@ -66,7 +66,7 @@
 		return nil
 	}
 	for _, x := range *ext {
-		ei := mi.extensionFieldInfo(x.Type())
+		ei := getExtensionFieldInfo(x.Type())
 		if ei.funcs.isInit == nil {
 			continue
 		}