From 7d9f8af42e2872245829c2b26c93d71625c38599 Mon Sep 17 00:00:00 2001 From: blakeli Date: Thu, 3 Apr 2025 22:59:54 -0600 Subject: [PATCH 1/2] Decouple ExtensionRegistryLite from GeneratedMessageLite.GeneratedExtension. --- .../com/google/protobuf/ArrayDecoders.java | 2 +- .../protobuf/ExtensionRegistryLite.java | 27 ++++++++++--------- .../google/protobuf/GeneratedMessageLite.java | 4 +-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/protobuf-api/src/main/java/com/google/protobuf/ArrayDecoders.java b/protobuf-api/src/main/java/com/google/protobuf/ArrayDecoders.java index bf5f922..331806b 100644 --- a/protobuf-api/src/main/java/com/google/protobuf/ArrayDecoders.java +++ b/protobuf-api/src/main/java/com/google/protobuf/ArrayDecoders.java @@ -765,7 +765,7 @@ static int decodeExtensionOrUnknownField( throws IOException { final int number = tag >>> 3; GeneratedMessageLite.GeneratedExtension extension = - registers.extensionRegistry.findLiteExtensionByNumber(defaultInstance, number); + (GeneratedMessageLite.GeneratedExtension) registers.extensionRegistry.findLiteExtensionByNumber(defaultInstance, number); if (extension == null) { return decodeUnknownField( tag, data, position, limit, getMutableUnknownFields(message), registers); diff --git a/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java index 18d14bf..769bffd 100644 --- a/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java +++ b/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java @@ -127,27 +127,30 @@ public ExtensionRegistryLite getUnmodifiable() { */ @SuppressWarnings("unchecked") public - GeneratedMessageLite.GeneratedExtension findLiteExtensionByNumber( + ExtensionLite findLiteExtensionByNumber( final ContainingType containingTypeDefaultInstance, final int fieldNumber) { - return (GeneratedMessageLite.GeneratedExtension) + return (ExtensionLite) extensionsByNumber.get(new ObjectIntPair(containingTypeDefaultInstance, fieldNumber)); } /** Add an extension from a lite generated file to the registry. */ - public final void add(final GeneratedMessageLite.GeneratedExtension extension) { - extensionsByNumber.put( - new ObjectIntPair(extension.getContainingTypeDefaultInstance(), extension.getNumber()), - extension); - } +// public final void add(final ExtensionLite extension) { +// extensionsByNumber.put( +// new ObjectIntPair(extension, extension.getNumber()), +// extension); +// } /** * Add an extension from a lite generated file to the registry only if it is a non-lite extension * i.e. {@link GeneratedMessageLite.GeneratedExtension}. */ public final void add(ExtensionLite extension) { - if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension.getClass())) { - add((GeneratedMessageLite.GeneratedExtension) extension); - } + extensionsByNumber.put( + new ObjectIntPair(extension, extension.getNumber()), + extension); +// if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension.getClass())) { +// add((GeneratedMessageLite.GeneratedExtension) extension); +// } if (doFullRuntimeInheritanceCheck && ExtensionRegistryFactory.isFullRegistry(this)) { try { this.getClass().getMethod("add", ExtensionClassHolder.INSTANCE).invoke(this, extension); @@ -166,7 +169,7 @@ public final void add(ExtensionLite extension) { ExtensionRegistryLite() { this.extensionsByNumber = - new HashMap>(); + new HashMap>(); } static final ExtensionRegistryLite EMPTY_REGISTRY_LITE = new ExtensionRegistryLite(true); @@ -179,7 +182,7 @@ public final void add(ExtensionLite extension) { } } - private final Map> + private final Map> extensionsByNumber; ExtensionRegistryLite(boolean empty) { diff --git a/protobuf-api/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/protobuf-api/src/main/java/com/google/protobuf/GeneratedMessageLite.java index c153960..8dfc01a 100644 --- a/protobuf-api/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/protobuf-api/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -623,7 +623,7 @@ protected boolean parseUnknownField( // TODO: How much bytecode would be saved by not requiring the generated code to // provide the default instance? GeneratedExtension extension = - extensionRegistry.findLiteExtensionByNumber(defaultInstance, fieldNumber); + (GeneratedExtension) extensionRegistry.findLiteExtensionByNumber(defaultInstance, fieldNumber); return parseExtension(input, extensionRegistry, extension, tag, fieldNumber); } @@ -808,7 +808,7 @@ private void mergeMessageSetExtensionFromCoded if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) { typeId = input.readUInt32(); if (typeId != 0) { - extension = extensionRegistry.findLiteExtensionByNumber(defaultInstance, typeId); + extension = (GeneratedExtension) extensionRegistry.findLiteExtensionByNumber(defaultInstance, typeId); } } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) { From c5bc454b21b6c0097f713f121ab5c104cbccf970 Mon Sep 17 00:00:00 2001 From: blakeli Date: Thu, 3 Apr 2025 23:18:55 -0600 Subject: [PATCH 2/2] Get GeneratedMessageLite$GeneratedExtension using reflection. --- .../protobuf/ExtensionRegistryLite.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java index 769bffd..03a2761 100644 --- a/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java +++ b/protobuf-api/src/main/java/com/google/protobuf/ExtensionRegistryLite.java @@ -7,6 +7,7 @@ package com.google.protobuf; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -72,6 +73,19 @@ static Class resolveExtensionClass() { } } } + private static final Class GENERATED_EXTENSION = getGeneratedExtensionClass(); + + private static Class getGeneratedExtensionClass() { + try { + Class generatedMessageLiteClass = Class.forName("com.google.protobuf.GeneratedMessageLite"); + return Arrays.stream(generatedMessageLiteClass.getClasses()) + .filter(innerClass -> innerClass.getName().equals("com.google.protobuf.GeneratedMessageLite$GeneratedExtension")) + .findFirst() + .get(); + } catch (Throwable e) { + return null; + } + } public static boolean isEagerlyParseMessageSets() { return eagerlyParseMessageSets; @@ -145,12 +159,11 @@ public ExtensionRegistryLite getUnmodifiable() { * i.e. {@link GeneratedMessageLite.GeneratedExtension}. */ public final void add(ExtensionLite extension) { - extensionsByNumber.put( - new ObjectIntPair(extension, extension.getNumber()), - extension); -// if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension.getClass())) { -// add((GeneratedMessageLite.GeneratedExtension) extension); -// } + if (GENERATED_EXTENSION.isAssignableFrom(extension.getClass())) { + extensionsByNumber.put( + new ObjectIntPair(extension, extension.getNumber()), + extension); + } if (doFullRuntimeInheritanceCheck && ExtensionRegistryFactory.isFullRegistry(this)) { try { this.getClass().getMethod("add", ExtensionClassHolder.INSTANCE).invoke(this, extension);