refactor: cache protobuf parser method lookup

Motivation:
Address PR review feedback that repeatedly calling MethodHandles.publicLookup() has unnecessary overhead while keeping the MethodHandle-based parser resolution behavior.

Modification:
Store a shared public Lookup for Java protobuf parser discovery and cache parser MethodHandles with a ConcurrentHashMap putIfAbsent pattern to avoid non-atomic TrieMap getOrElseUpdate lookup races.

Result:
ProtoAnySerialization reuses the public lookup and aligns parser handle caching with the existing ConsumerFilterStore MethodHandle cache style.

Tests:
- scalafmt --mode diff-ref=origin/main
- scalafmt --list --mode diff-ref=origin/main
- sbt "grpc-test / Test / testOnly org.apache.pekko.projection.grpc.internal.ProtoAnySerializationSpec"
- sbt "jdbc / Test / testOnly org.apache.pekko.projection.jdbc.JdbcProjectionTest org.apache.pekko.projection.jdbc.JdbcOffsetStoreSpec"
- sbt "jdbc / Test / testOnly org.apache.pekko.projection.jdbc.H2JdbcOffsetStoreSpec"
- sbt "jdbc-int-test / Test / testOnly org.apache.pekko.projection.jdbc.JdbcProjectionSpec"
- sbt "examples / Test / compile"
- git diff --check
- qodercli stdout review: No must-fix findings (/tmp/project-qoder-review-2.log)

References:
Refs apache/pekko-projection#561
diff --git a/grpc/src/main/scala/org/apache/pekko/projection/grpc/internal/ProtoAnySerialization.scala b/grpc/src/main/scala/org/apache/pekko/projection/grpc/internal/ProtoAnySerialization.scala
index 39078e6..09a8afa 100644
--- a/grpc/src/main/scala/org/apache/pekko/projection/grpc/internal/ProtoAnySerialization.scala
+++ b/grpc/src/main/scala/org/apache/pekko/projection/grpc/internal/ProtoAnySerialization.scala
@@ -14,6 +14,7 @@
 package org.apache.pekko.projection.grpc.internal
 
 import java.lang.invoke.{ MethodHandle, MethodHandles, MethodType }
+import java.util.concurrent.ConcurrentHashMap
 
 import scala.collection.concurrent.TrieMap
 import scala.collection.immutable
@@ -45,8 +46,9 @@
   final val PekkoSerializationTypeUrlPrefix = "ser.pekko.io/"
   final val PekkoTypeUrlManifestSeparator = ':'
   private final val ProtoAnyTypeUrl = GoogleTypeUrlPrefix + "google.protobuf.Any"
+  private val publicLookup = MethodHandles.publicLookup()
   private val parserMethodType = MethodType.methodType(classOf[Parser[?]])
-  private val parserHandles = TrieMap.empty[Class[?], MethodHandle]
+  private val parserHandles = new ConcurrentHashMap[Class[?], MethodHandle]
 
   private val log = LoggerFactory.getLogger(classOf[ProtoAnySerialization])
 
@@ -246,8 +248,15 @@
     }
   }
 
-  private def parserHandle(clazz: Class[?]): MethodHandle =
-    parserHandles.getOrElseUpdate(clazz, MethodHandles.publicLookup().findStatic(clazz, "parser", parserMethodType))
+  private def parserHandle(clazz: Class[?]): MethodHandle = {
+    val cached = parserHandles.get(clazz)
+    if (cached ne null) cached
+    else {
+      val handle = publicLookup.findStatic(clazz, "parser", parserMethodType)
+      val existing = parserHandles.putIfAbsent(clazz, handle)
+      if (existing eq null) handle else existing
+    }
+  }
 
   private def hasExtension[ContainerT <: com.google.protobuf.GeneratedMessage.ExtendableMessage[ContainerT], T](
       msg: com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder[ContainerT],