diff options
author | Protobuf Team Bot <protobuf-github-bot@google.com> | 2024-05-09 15:52:11 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-05-09 15:54:16 -0700 |
commit | fefec687536234a46f96d0c6e209dabceaf18466 (patch) | |
tree | 74c31258d67a09130aa81466c10cd41a2178d499 | |
parent | af1ecc03531461900c1c9b8499aa64f5900bca27 (diff) | |
download | protobuf-fefec687536234a46f96d0c6e209dabceaf18466.tar.gz |
Internal changes/optimizations
PiperOrigin-RevId: 632294209
12 files changed, 228 insertions, 188 deletions
diff --git a/java/core/BUILD.bazel b/java/core/BUILD.bazel index 683b0654a..6127b4c5c 100644 --- a/java/core/BUILD.bazel +++ b/java/core/BUILD.bazel @@ -60,6 +60,8 @@ LITE_SRCS = [ "src/main/java/com/google/protobuf/LazyStringArrayList.java", "src/main/java/com/google/protobuf/LazyStringList.java", "src/main/java/com/google/protobuf/ListFieldSchema.java", + "src/main/java/com/google/protobuf/ListFieldSchemaLite.java", + "src/main/java/com/google/protobuf/ListFieldSchemas.java", "src/main/java/com/google/protobuf/LongArrayList.java", "src/main/java/com/google/protobuf/ManifestSchemaFactory.java", "src/main/java/com/google/protobuf/MapEntryLite.java", diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java index cd8c852e9..5f0ce0668 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java @@ -31,4 +31,6 @@ final class ExtensionSchemas { } return FULL_SCHEMA; } + + private ExtensionSchemas() {} } diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java index bc55eb23c..eaab68b8d 100644 --- a/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java +++ b/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java @@ -7,162 +7,17 @@ package com.google.protobuf; -import com.google.protobuf.Internal.ProtobufList; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** * Utility class that aids in properly manipulating list fields for either the lite or full runtime. */ @CheckReturnValue -abstract class ListFieldSchema { - // Disallow construction. - private ListFieldSchema() {} +interface ListFieldSchema { - private static final ListFieldSchema FULL_INSTANCE = new ListFieldSchemaFull(); - private static final ListFieldSchema LITE_INSTANCE = new ListFieldSchemaLite(); + <L> List<L> mutableListAt(Object msg, long offset); - abstract <L> List<L> mutableListAt(Object msg, long offset); + void makeImmutableListAt(Object msg, long offset); - abstract void makeImmutableListAt(Object msg, long offset); - - abstract <L> void mergeListsAt(Object msg, Object otherMsg, long offset); - - static ListFieldSchema full() { - return FULL_INSTANCE; - } - - static ListFieldSchema lite() { - return LITE_INSTANCE; - } - - /** Implementation for the full runtime. */ - private static final class ListFieldSchemaFull extends ListFieldSchema { - - private static final Class<?> UNMODIFIABLE_LIST_CLASS = - Collections.unmodifiableList(Collections.emptyList()).getClass(); - - @Override - <L> List<L> mutableListAt(Object message, long offset) { - return mutableListAt(message, offset, AbstractProtobufList.DEFAULT_CAPACITY); - } - - @Override - void makeImmutableListAt(Object message, long offset) { - List<?> list = (List<?>) UnsafeUtil.getObject(message, offset); - Object immutable = null; - if (list instanceof LazyStringList) { - immutable = ((LazyStringList) list).getUnmodifiableView(); - } else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) { - // already immutable - return; - } else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) { - if (((ProtobufList<?>) list).isModifiable()) { - ((ProtobufList<?>) list).makeImmutable(); - } - return; - } else { - immutable = Collections.unmodifiableList((List<?>) list); - } - UnsafeUtil.putObject(message, offset, immutable); - } - - @SuppressWarnings("unchecked") - private static <L> List<L> mutableListAt(Object message, long offset, int additionalCapacity) { - List<L> list = getList(message, offset); - if (list.isEmpty()) { - if (list instanceof LazyStringList) { - list = (List<L>) new LazyStringArrayList(additionalCapacity); - } else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) { - list = ((ProtobufList<L>) list).mutableCopyWithCapacity(additionalCapacity); - } else { - list = new ArrayList<L>(additionalCapacity); - } - UnsafeUtil.putObject(message, offset, list); - } else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) { - ArrayList<L> newList = new ArrayList<L>(list.size() + additionalCapacity); - newList.addAll(list); - list = newList; - UnsafeUtil.putObject(message, offset, list); - } else if (list instanceof UnmodifiableLazyStringList) { - LazyStringArrayList newList = new LazyStringArrayList(list.size() + additionalCapacity); - newList.addAll((UnmodifiableLazyStringList) list); - list = (List<L>) newList; - UnsafeUtil.putObject(message, offset, list); - } else if (list instanceof PrimitiveNonBoxingCollection - && list instanceof ProtobufList - && !((ProtobufList<L>) list).isModifiable()) { - list = ((ProtobufList<L>) list).mutableCopyWithCapacity(list.size() + additionalCapacity); - UnsafeUtil.putObject(message, offset, list); - } - return list; - } - - @Override - <E> void mergeListsAt(Object msg, Object otherMsg, long offset) { - List<E> other = getList(otherMsg, offset); - List<E> mine = mutableListAt(msg, offset, other.size()); - - int size = mine.size(); - int otherSize = other.size(); - if (size > 0 && otherSize > 0) { - mine.addAll(other); - } - - List<E> merged = size > 0 ? mine : other; - UnsafeUtil.putObject(msg, offset, merged); - } - - @SuppressWarnings("unchecked") - static <E> List<E> getList(Object message, long offset) { - return (List<E>) UnsafeUtil.getObject(message, offset); - } - } - - /** Implementation for the lite runtime. */ - private static final class ListFieldSchemaLite extends ListFieldSchema { - - @Override - <L> List<L> mutableListAt(Object message, long offset) { - ProtobufList<L> list = getProtobufList(message, offset); - if (!list.isModifiable()) { - int size = list.size(); - list = - list.mutableCopyWithCapacity( - size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2); - UnsafeUtil.putObject(message, offset, list); - } - return list; - } - - @Override - void makeImmutableListAt(Object message, long offset) { - ProtobufList<?> list = getProtobufList(message, offset); - list.makeImmutable(); - } - - @Override - <E> void mergeListsAt(Object msg, Object otherMsg, long offset) { - ProtobufList<E> mine = getProtobufList(msg, offset); - ProtobufList<E> other = getProtobufList(otherMsg, offset); - - int size = mine.size(); - int otherSize = other.size(); - if (size > 0 && otherSize > 0) { - if (!mine.isModifiable()) { - mine = mine.mutableCopyWithCapacity(size + otherSize); - } - mine.addAll(other); - } - - ProtobufList<E> merged = size > 0 ? mine : other; - UnsafeUtil.putObject(msg, offset, merged); - } - - @SuppressWarnings("unchecked") - static <E> ProtobufList<E> getProtobufList(Object message, long offset) { - return (ProtobufList<E>) UnsafeUtil.getObject(message, offset); - } - } + <L> void mergeListsAt(Object msg, Object otherMsg, long offset); } diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchemaFull.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchemaFull.java new file mode 100644 index 000000000..8f0308ab6 --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/ListFieldSchemaFull.java @@ -0,0 +1,99 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +import com.google.protobuf.Internal.ProtobufList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Utility class that aids in properly manipulating list fields for either the lite or full runtime. + */ +@CheckReturnValue +final class ListFieldSchemaFull implements ListFieldSchema { + + private static final Class<?> UNMODIFIABLE_LIST_CLASS = + Collections.unmodifiableList(Collections.emptyList()).getClass(); + + @Override + public <L> List<L> mutableListAt(Object message, long offset) { + return mutableListAt(message, offset, AbstractProtobufList.DEFAULT_CAPACITY); + } + + @SuppressWarnings("unchecked") + private static <L> List<L> mutableListAt(Object message, long offset, int additionalCapacity) { + List<L> list = getList(message, offset); + if (list.isEmpty()) { + if (list instanceof LazyStringList) { + list = (List<L>) new LazyStringArrayList(additionalCapacity); + } else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) { + list = ((ProtobufList<L>) list).mutableCopyWithCapacity(additionalCapacity); + } else { + list = new ArrayList<L>(additionalCapacity); + } + UnsafeUtil.putObject(message, offset, list); + } else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) { + ArrayList<L> newList = new ArrayList<L>(list.size() + additionalCapacity); + newList.addAll(list); + list = newList; + UnsafeUtil.putObject(message, offset, list); + } else if (list instanceof UnmodifiableLazyStringList) { + LazyStringArrayList newList = new LazyStringArrayList(list.size() + additionalCapacity); + newList.addAll((UnmodifiableLazyStringList) list); + list = (List<L>) newList; + UnsafeUtil.putObject(message, offset, list); + } else if (list instanceof PrimitiveNonBoxingCollection + && list instanceof ProtobufList + && !((ProtobufList<L>) list).isModifiable()) { + list = ((ProtobufList<L>) list).mutableCopyWithCapacity(list.size() + additionalCapacity); + UnsafeUtil.putObject(message, offset, list); + } + return list; + } + + @Override + public void makeImmutableListAt(Object message, long offset) { + List<?> list = (List<?>) UnsafeUtil.getObject(message, offset); + Object immutable = null; + if (list instanceof LazyStringList) { + immutable = ((LazyStringList) list).getUnmodifiableView(); + } else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) { + // already immutable + return; + } else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) { + if (((ProtobufList<?>) list).isModifiable()) { + ((ProtobufList<?>) list).makeImmutable(); + } + return; + } else { + immutable = Collections.unmodifiableList((List<?>) list); + } + UnsafeUtil.putObject(message, offset, immutable); + } + + @Override + public <E> void mergeListsAt(Object msg, Object otherMsg, long offset) { + List<E> other = getList(otherMsg, offset); + List<E> mine = mutableListAt(msg, offset, other.size()); + + int size = mine.size(); + int otherSize = other.size(); + if (size > 0 && otherSize > 0) { + mine.addAll(other); + } + + List<E> merged = size > 0 ? mine : other; + UnsafeUtil.putObject(msg, offset, merged); + } + + @SuppressWarnings("unchecked") + static <E> List<E> getList(Object message, long offset) { + return (List<E>) UnsafeUtil.getObject(message, offset); + } +} diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java new file mode 100644 index 000000000..f0cf71ecc --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java @@ -0,0 +1,59 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +import com.google.protobuf.Internal.ProtobufList; +import java.util.List; + +/** + * Utility class that aids in properly manipulating list fields for either the lite or full runtime. + */ +final class ListFieldSchemaLite implements ListFieldSchema { + + @Override + public <L> List<L> mutableListAt(Object message, long offset) { + ProtobufList<L> list = getProtobufList(message, offset); + if (!list.isModifiable()) { + int size = list.size(); + list = + list.mutableCopyWithCapacity( + size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2); + UnsafeUtil.putObject(message, offset, list); + } + return list; + } + + @Override + public void makeImmutableListAt(Object message, long offset) { + ProtobufList<?> list = getProtobufList(message, offset); + list.makeImmutable(); + } + + @Override + public <E> void mergeListsAt(Object msg, Object otherMsg, long offset) { + ProtobufList<E> mine = getProtobufList(msg, offset); + ProtobufList<E> other = getProtobufList(otherMsg, offset); + + int size = mine.size(); + int otherSize = other.size(); + if (size > 0 && otherSize > 0) { + if (!mine.isModifiable()) { + mine = mine.mutableCopyWithCapacity(size + otherSize); + } + mine.addAll(other); + } + + ProtobufList<E> merged = size > 0 ? mine : other; + UnsafeUtil.putObject(msg, offset, merged); + } + + @SuppressWarnings("unchecked") + static <E> ProtobufList<E> getProtobufList(Object message, long offset) { + return (ProtobufList<E>) UnsafeUtil.getObject(message, offset); + } +} diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchemas.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchemas.java new file mode 100644 index 000000000..6250b7a2d --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/ListFieldSchemas.java @@ -0,0 +1,33 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +@CheckReturnValue +final class ListFieldSchemas { + private static final ListFieldSchema FULL_SCHEMA = loadSchemaForFullRuntime(); + private static final ListFieldSchema LITE_SCHEMA = new ListFieldSchemaLite(); + + static ListFieldSchema full() { + return FULL_SCHEMA; + } + + static ListFieldSchema lite() { + return LITE_SCHEMA; + } + + private static ListFieldSchema loadSchemaForFullRuntime() { + try { + Class<?> clazz = Class.forName("com.google.protobuf.ListFieldSchemaFull"); + return (ListFieldSchema) clazz.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + return null; + } + } + + private ListFieldSchemas() {} +} diff --git a/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java b/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java index c923b129d..9b4fd82d4 100644 --- a/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java +++ b/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java @@ -34,57 +34,37 @@ final class ManifestSchemaFactory implements SchemaFactory { // MessageSet has a special schema. if (messageInfo.isMessageSetWireFormat()) { - if (GeneratedMessageLite.class.isAssignableFrom(messageType)) { - return MessageSetSchema.newSchema( - SchemaUtil.unknownFieldSetLiteSchema(), - ExtensionSchemas.lite(), - messageInfo.getDefaultInstance()); - } - return MessageSetSchema.newSchema( - SchemaUtil.unknownFieldSetFullSchema(), - ExtensionSchemas.full(), - messageInfo.getDefaultInstance()); + return useLiteRuntime(messageType) + ? MessageSetSchema.newSchema( + SchemaUtil.unknownFieldSetLiteSchema(), + ExtensionSchemas.lite(), + messageInfo.getDefaultInstance()) + : MessageSetSchema.newSchema( + SchemaUtil.unknownFieldSetFullSchema(), + ExtensionSchemas.full(), + messageInfo.getDefaultInstance()); } return newSchema(messageType, messageInfo); } private static <T> Schema<T> newSchema(Class<T> messageType, MessageInfo messageInfo) { - if (GeneratedMessageLite.class.isAssignableFrom(messageType)) { - return allowExtensions(messageInfo) - ? MessageSchema.newSchema( - messageType, - messageInfo, - NewInstanceSchemas.lite(), - ListFieldSchema.lite(), - SchemaUtil.unknownFieldSetLiteSchema(), - ExtensionSchemas.lite(), - MapFieldSchemas.lite()) - : MessageSchema.newSchema( - messageType, - messageInfo, - NewInstanceSchemas.lite(), - ListFieldSchema.lite(), - SchemaUtil.unknownFieldSetLiteSchema(), - /* extensionSchema= */ null, - MapFieldSchemas.lite()); - } - return allowExtensions(messageInfo) + return useLiteRuntime(messageType) ? MessageSchema.newSchema( messageType, messageInfo, - NewInstanceSchemas.full(), - ListFieldSchema.full(), - SchemaUtil.unknownFieldSetFullSchema(), - ExtensionSchemas.full(), - MapFieldSchemas.full()) + NewInstanceSchemas.lite(), + ListFieldSchemas.lite(), + SchemaUtil.unknownFieldSetLiteSchema(), + allowExtensions(messageInfo) ? ExtensionSchemas.lite() : null, + MapFieldSchemas.lite()) : MessageSchema.newSchema( messageType, messageInfo, NewInstanceSchemas.full(), - ListFieldSchema.full(), + ListFieldSchemas.full(), SchemaUtil.unknownFieldSetFullSchema(), - /* extensionSchema= */ null, + allowExtensions(messageInfo) ? ExtensionSchemas.full() : null, MapFieldSchemas.full()); } @@ -152,4 +132,8 @@ final class ManifestSchemaFactory implements SchemaFactory { return EMPTY_FACTORY; } } + + private static boolean useLiteRuntime(Class<?> messageType) { + return GeneratedMessageLite.class.isAssignableFrom(messageType); + } } diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaFull.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaFull.java index d41144917..624c258d4 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaFull.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaFull.java @@ -10,7 +10,7 @@ package com.google.protobuf; import com.google.protobuf.MapEntryLite.Metadata; import java.util.Map; -class MapFieldSchemaFull implements MapFieldSchema { +final class MapFieldSchemaFull implements MapFieldSchema { @Override public Map<?, ?> forMutableMapData(Object mapField) { return ((MapField<?, ?>) mapField).getMutableMap(); diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java index f7c5d85f3..c21678d28 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java @@ -11,7 +11,7 @@ import com.google.protobuf.MapEntryLite.Metadata; import java.util.Map; @CheckReturnValue -class MapFieldSchemaLite implements MapFieldSchema { +final class MapFieldSchemaLite implements MapFieldSchema { @Override public Map<?, ?> forMutableMapData(Object mapField) { diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java index d7eeccd8c..ea419a56c 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java @@ -28,4 +28,6 @@ final class MapFieldSchemas { return null; } } + + private MapFieldSchemas() {} } diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java index 800f44891..6fbdd47a3 100644 --- a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java +++ b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java @@ -28,4 +28,6 @@ final class NewInstanceSchemas { return null; } } + + private NewInstanceSchemas() {} } diff --git a/java/lite/pom.xml b/java/lite/pom.xml index 64a69085f..d2da13084 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -139,6 +139,8 @@ <include>LazyStringArrayList.java</include> <include>LazyStringList.java</include> <include>ListFieldSchema.java</include> + <include>ListFieldSchemaLite.java</include> + <include>ListFieldSchemas.java</include> <include>LongArrayList.java</include> <include>ManifestSchemaFactory.java</include> <include>MapEntryLite.java</include> |