summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2025-09-22 12:52:08 +0000
committerCoprDistGit <infra@openeuler.org>2025-09-22 12:52:08 +0000
commit62193eb291a15f336c66a3e3eb1f95b94fc0d022 (patch)
tree97229163558c23c22ced9d1499e901dd68126bdf
parent7572f9f90d38d06d944a23a0f5672962ae7b83b6 (diff)
automatic import of protobuf
-rw-r--r--0001-add-secure-compile-option-in-Makefile.patch12
-rw-r--r--0001-add-secure-compile-option.patch27
-rw-r--r--0002-Fix-CC-compiler-support.patch29
-rw-r--r--0002-add-secure-compile-fs-check-in-Makefile.patch26
-rw-r--r--0003-protobuf-add-coverage-compile-option.patch27
-rw-r--r--0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch1272
-rw-r--r--0007-add-coverage-compile-option.patch49
-rw-r--r--protobuf.spec232
8 files changed, 1409 insertions, 265 deletions
diff --git a/0001-add-secure-compile-option-in-Makefile.patch b/0001-add-secure-compile-option-in-Makefile.patch
new file mode 100644
index 0000000..988ba43
--- /dev/null
+++ b/0001-add-secure-compile-option-in-Makefile.patch
@@ -0,0 +1,12 @@
+diff --git a/src/Makefile.am b/src/Makefile.am
+index f1099d9..9b7053b 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -19,6 +19,7 @@ PTHREAD_DEF =
+ endif
+
+ PROTOBUF_VERSION = 25:0:0
++PROTOBUF_OPT_FLAG += -Wl,-z,now
+
+ if GCC
+ # Turn on all warnings except for sign comparison (we ignore sign comparison
diff --git a/0001-add-secure-compile-option.patch b/0001-add-secure-compile-option.patch
deleted file mode 100644
index 0594f0e..0000000
--- a/0001-add-secure-compile-option.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 4cf6dc9f628fc2c5b3478d70e15d4fab8a32ae86 Mon Sep 17 00:00:00 2001
-From: zhongtao <zhongtao17@huawei.com>
-Date: Wed, 10 Apr 2024 11:43:51 +0800
-Subject: [PATCH] add secure compile option
-
-Signed-off-by: zhongtao <zhongtao17@huawei.com>
----
- CMakeLists.txt | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 4137ce2..d17f09d 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -2,6 +2,9 @@
- # to 3.26.
- cmake_minimum_required(VERSION 3.10...3.26)
-
-+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-z,now -fstack-check -fPIE")
-+set(CMAKE_EXE_LINKER_FLAGS "-pie")
-+
- # Revert to old behavior for MSVC debug symbols.
- if(POLICY CMP0141)
- cmake_policy(SET CMP0141 OLD)
---
-2.25.1
-
diff --git a/0002-Fix-CC-compiler-support.patch b/0002-Fix-CC-compiler-support.patch
deleted file mode 100644
index d4f4440..0000000
--- a/0002-Fix-CC-compiler-support.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From b62fbe3852ea070f1bfbb048e71dfae70c7c71f0 Mon Sep 17 00:00:00 2001
-From: wangqiang <wangqiang1@kylinos.cn>
-Date: Tue, 19 Mar 2024 18:54:13 +0800
-Subject: [PATCH] Fix CC compiler support
-
----
- third_party/utf8_range/utf8_to_utf16/Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/third_party/utf8_range/utf8_to_utf16/Makefile b/third_party/utf8_range/utf8_to_utf16/Makefile
-index 853ffa4..30ef021 100644
---- a/third_party/utf8_range/utf8_to_utf16/Makefile
-+++ b/third_party/utf8_range/utf8_to_utf16/Makefile
-@@ -1,10 +1,10 @@
--CC = gcc
-+CC := ${CC}
- CPPFLAGS = -g -O3 -Wall -march=native
-
- OBJS = main.o iconv.o naive.o
-
- utf8to16: ${OBJS}
-- gcc $^ -o $@
-+ ${CC} $^ -o $@
-
- .PHONY: clean
- clean:
---
-2.33.0
-
diff --git a/0002-add-secure-compile-fs-check-in-Makefile.patch b/0002-add-secure-compile-fs-check-in-Makefile.patch
new file mode 100644
index 0000000..9a5ff52
--- /dev/null
+++ b/0002-add-secure-compile-fs-check-in-Makefile.patch
@@ -0,0 +1,26 @@
+From dddceb14106499f9fca17e75cdce458a205b102c Mon Sep 17 00:00:00 2001
+From: haozi007 <liuhao27@huawei.com>
+Date: Sat, 20 Feb 2021 16:52:15 +0800
+Subject: [PATCH] add secure compile fs check in Makefile
+
+Signed-off-by: haozi007 <liuhao27@huawei.com>
+---
+ src/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 9b7053b..e447b05 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -19,7 +19,7 @@ PTHREAD_DEF =
+ endif
+
+ PROTOBUF_VERSION = 25:0:0
+-PROTOBUF_OPT_FLAG += -Wl,-z,now
++PROTOBUF_OPT_FLAG += -Wl,-z,now -fstack-check
+
+ if GCC
+ # Turn on all warnings except for sign comparison (we ignore sign comparison
+--
+2.25.1
+
diff --git a/0003-protobuf-add-coverage-compile-option.patch b/0003-protobuf-add-coverage-compile-option.patch
deleted file mode 100644
index 7a6aa17..0000000
--- a/0003-protobuf-add-coverage-compile-option.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From ea6d56c3518dc3af0f326f52a266bc0986d8635c Mon Sep 17 00:00:00 2001
-From: zhongtao <zhongtao17@huawei.com>
-Date: Thu, 25 Jul 2024 21:42:22 +0800
-Subject: [PATCH] protobuf: add coverage compile option
-
-Signed-off-by: zhongtao <zhongtao17@huawei.com>
----
- CMakeLists.txt | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index d17f09d..0b169f3 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -4,6 +4,9 @@ cmake_minimum_required(VERSION 3.10...3.26)
-
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-z,now -fstack-check -fPIE")
- set(CMAKE_EXE_LINKER_FLAGS "-pie")
-+if (ENABLE_CONVERAGE)
-+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
-+endif()
-
- # Revert to old behavior for MSVC debug symbols.
- if(POLICY CMP0141)
---
-2.25.1
-
diff --git a/0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch b/0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch
new file mode 100644
index 0000000..a56f88d
--- /dev/null
+++ b/0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch
@@ -0,0 +1,1272 @@
+From 8890b0a81e2f4b1de4a33cc6d81aba07655bde1a Mon Sep 17 00:00:00 2001
+From: wangxiaochao <wangxiaochao2@huawei.com>
+Date: Thu, 24 Mar 2022 20:54:36 +0800
+Subject: [PATCH] Improve performance of parsing unknown fields in Java
+
+Signed-off-by: wangxiaochao <wangxiaochao2@huawei.com>
+
+---
+ Makefile.am | 1 +
+ .../com/google/protobuf/UnknownFieldSet.java | 427 +++++++++---------
+ .../UnknownFieldSetPerformanceTest.java | 78 ++++
+ .../google/protobuf/UnknownFieldSetTest.java | 171 ++++++-
+ java/lite/pom.xml | 3 +-
+ 5 files changed, 466 insertions(+), 214 deletions(-)
+ create mode 100644 java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java
+
+diff --git a/Makefile.am b/Makefile.am
+index 4fc706b..908c2d2 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -487,6 +487,7 @@ java_EXTRA_DIST=
+ java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java \
+ java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \
+ java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \
++ java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java \
+ java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
+ java/core/src/test/java/com/google/protobuf/Utf8Test.java \
+ java/core/src/test/java/com/google/protobuf/Utf8Utils.java \
+diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
+index ba2f9df..5c482d6 100644
+--- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
++++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
+@@ -43,13 +43,13 @@ import java.util.Map;
+ import java.util.TreeMap;
+
+ /**
+- * {@code UnknownFieldSet} is used to keep track of fields which were seen when parsing a protocol
++ * {@code UnknownFieldSet} keeps track of fields which were seen when parsing a protocol
+ * message but whose field numbers or types are unrecognized. This most frequently occurs when new
+ * fields are added to a message type and then messages containing those fields are read by old
+ * software that was compiled before the new types were added.
+ *
+ * <p>Every {@link Message} contains an {@code UnknownFieldSet} (and every {@link Message.Builder}
+- * contains an {@link Builder}).
++ * contains a {@link Builder}).
+ *
+ * <p>Most users will never need to use this class.
+ *
+@@ -57,9 +57,13 @@ import java.util.TreeMap;
+ */
+ public final class UnknownFieldSet implements MessageLite {
+
+- private UnknownFieldSet() {
+- fields = null;
+- fieldsDescending = null;
++ private final TreeMap<Integer, Field> fields;
++
++ /**
++ * Construct an {@code UnknownFieldSet} around the given map.
++ */
++ UnknownFieldSet(TreeMap<Integer, Field> fields) {
++ this.fields = fields;
+ }
+
+ /** Create a new {@link Builder}. */
+@@ -68,7 +72,7 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ /** Create a new {@link Builder} and initialize it to be a copy of {@code copyFrom}. */
+- public static Builder newBuilder(final UnknownFieldSet copyFrom) {
++ public static Builder newBuilder(UnknownFieldSet copyFrom) {
+ return newBuilder().mergeFrom(copyFrom);
+ }
+
+@@ -83,25 +87,11 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ private static final UnknownFieldSet defaultInstance =
+- new UnknownFieldSet(
+- Collections.<Integer, Field>emptyMap(), Collections.<Integer, Field>emptyMap());
+-
+- /**
+- * Construct an {@code UnknownFieldSet} around the given map. The map is expected to be immutable.
+- */
+- UnknownFieldSet(final Map<Integer, Field> fields, final Map<Integer, Field> fieldsDescending) {
+- this.fields = fields;
+- this.fieldsDescending = fieldsDescending;
+- }
+-
+- private final Map<Integer, Field> fields;
+-
+- /** A copy of {@link #fields} who's iterator order is reversed. */
+- private final Map<Integer, Field> fieldsDescending;
++ new UnknownFieldSet(new TreeMap<Integer, Field>());
+
+
+ @Override
+- public boolean equals(final Object other) {
++ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+@@ -110,29 +100,33 @@ public final class UnknownFieldSet implements MessageLite {
+
+ @Override
+ public int hashCode() {
++ if (fields.isEmpty()) { // avoid allocation of iterator.
++ // This optimization may not be helpful but it is needed for the allocation tests to pass.
++ return 0;
++ }
+ return fields.hashCode();
+ }
+
+ /** Get a map of fields in the set by number. */
+ public Map<Integer, Field> asMap() {
+- return fields;
++ return (Map<Integer, Field>) fields.clone();
+ }
+
+ /** Check if the given field number is present in the set. */
+- public boolean hasField(final int number) {
++ public boolean hasField(int number) {
+ return fields.containsKey(number);
+ }
+
+ /** Get a field by number. Returns an empty field if not present. Never returns {@code null}. */
+- public Field getField(final int number) {
+- final Field result = fields.get(number);
++ public Field getField(int number) {
++ Field result = fields.get(number);
+ return (result == null) ? Field.getDefaultInstance() : result;
+ }
+
+ /** Serializes the set and writes it to {@code output}. */
+ @Override
+- public void writeTo(final CodedOutputStream output) throws IOException {
+- for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
++ public void writeTo(CodedOutputStream output) throws IOException {
++ for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ Field field = entry.getValue();
+ field.writeTo(entry.getKey(), output);
+ }
+@@ -154,10 +148,10 @@ public final class UnknownFieldSet implements MessageLite {
+ @Override
+ public ByteString toByteString() {
+ try {
+- final ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize());
++ ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize());
+ writeTo(out.getCodedOutput());
+ return out.build();
+- } catch (final IOException e) {
++ } catch (IOException e) {
+ throw new RuntimeException(
+ "Serializing to a ByteString threw an IOException (should never happen).", e);
+ }
+@@ -170,12 +164,12 @@ public final class UnknownFieldSet implements MessageLite {
+ @Override
+ public byte[] toByteArray() {
+ try {
+- final byte[] result = new byte[getSerializedSize()];
+- final CodedOutputStream output = CodedOutputStream.newInstance(result);
++ byte[] result = new byte[getSerializedSize()];
++ CodedOutputStream output = CodedOutputStream.newInstance(result);
+ writeTo(output);
+ output.checkNoSpaceLeft();
+ return result;
+- } catch (final IOException e) {
++ } catch (IOException e) {
+ throw new RuntimeException(
+ "Serializing to a byte array threw an IOException (should never happen).", e);
+ }
+@@ -186,16 +180,16 @@ public final class UnknownFieldSet implements MessageLite {
+ * {@link #writeTo(CodedOutputStream)}.
+ */
+ @Override
+- public void writeTo(final OutputStream output) throws IOException {
+- final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
++ public void writeTo(OutputStream output) throws IOException {
++ CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+ writeTo(codedOutput);
+ codedOutput.flush();
+ }
+
+ @Override
+ public void writeDelimitedTo(OutputStream output) throws IOException {
+- final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+- codedOutput.writeRawVarint32(getSerializedSize());
++ CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
++ codedOutput.writeUInt32NoTag(getSerializedSize());
+ writeTo(codedOutput);
+ codedOutput.flush();
+ }
+@@ -204,15 +198,17 @@ public final class UnknownFieldSet implements MessageLite {
+ @Override
+ public int getSerializedSize() {
+ int result = 0;
+- for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+- result += entry.getValue().getSerializedSize(entry.getKey());
++ if (!fields.isEmpty()) {
++ for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
++ result += entry.getValue().getSerializedSize(entry.getKey());
++ }
+ }
+ return result;
+ }
+
+ /** Serializes the set and writes it to {@code output} using {@code MessageSet} wire format. */
+- public void writeAsMessageSetTo(final CodedOutputStream output) throws IOException {
+- for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
++ public void writeAsMessageSetTo(CodedOutputStream output) throws IOException {
++ for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), output);
+ }
+ }
+@@ -221,7 +217,7 @@ public final class UnknownFieldSet implements MessageLite {
+ void writeTo(Writer writer) throws IOException {
+ if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
+ // Write fields in descending order.
+- for (Map.Entry<Integer, Field> entry : fieldsDescending.entrySet()) {
++ for (Map.Entry<Integer, Field> entry : fields.descendingMap().entrySet()) {
+ entry.getValue().writeTo(entry.getKey(), writer);
+ }
+ } else {
+@@ -233,15 +229,15 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ /** Serializes the set and writes it to {@code writer} using {@code MessageSet} wire format. */
+- void writeAsMessageSetTo(final Writer writer) throws IOException {
++ void writeAsMessageSetTo(Writer writer) throws IOException {
+ if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
+ // Write fields in descending order.
+- for (final Map.Entry<Integer, Field> entry : fieldsDescending.entrySet()) {
++ for (Map.Entry<Integer, Field> entry : fields.descendingMap().entrySet()) {
+ entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer);
+ }
+ } else {
+ // Write fields in ascending order.
+- for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
++ for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer);
+ }
+ }
+@@ -250,7 +246,7 @@ public final class UnknownFieldSet implements MessageLite {
+ /** Get the number of bytes required to encode this set using {@code MessageSet} wire format. */
+ public int getSerializedSizeAsMessageSet() {
+ int result = 0;
+- for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
++ for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ result += entry.getValue().getSerializedSizeAsMessageSetExtension(entry.getKey());
+ }
+ return result;
+@@ -264,23 +260,23 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ /** Parse an {@code UnknownFieldSet} from the given input stream. */
+- public static UnknownFieldSet parseFrom(final CodedInputStream input) throws IOException {
++ public static UnknownFieldSet parseFrom(CodedInputStream input) throws IOException {
+ return newBuilder().mergeFrom(input).build();
+ }
+
+ /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
+- public static UnknownFieldSet parseFrom(final ByteString data)
++ public static UnknownFieldSet parseFrom(ByteString data)
+ throws InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).build();
+ }
+
+ /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
+- public static UnknownFieldSet parseFrom(final byte[] data) throws InvalidProtocolBufferException {
++ public static UnknownFieldSet parseFrom(byte[] data) throws InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).build();
+ }
+
+ /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */
+- public static UnknownFieldSet parseFrom(final InputStream input) throws IOException {
++ public static UnknownFieldSet parseFrom(InputStream input) throws IOException {
+ return newBuilder().mergeFrom(input).build();
+ }
+
+@@ -309,64 +305,43 @@ public final class UnknownFieldSet implements MessageLite {
+ // This constructor should never be called directly (except from 'create').
+ private Builder() {}
+
+- private Map<Integer, Field> fields;
+-
+- // Optimization: We keep around a builder for the last field that was
+- // modified so that we can efficiently add to it multiple times in a
+- // row (important when parsing an unknown repeated field).
+- private int lastFieldNumber;
+- private Field.Builder lastField;
++ private TreeMap<Integer, Field.Builder> fieldBuilders = new TreeMap<>();
+
+ private static Builder create() {
+- Builder builder = new Builder();
+- builder.reinitialize();
+- return builder;
++ return new Builder();
+ }
+
+ /**
+ * Get a field builder for the given field number which includes any values that already exist.
+ */
+- private Field.Builder getFieldBuilder(final int number) {
+- if (lastField != null) {
+- if (number == lastFieldNumber) {
+- return lastField;
+- }
+- // Note: addField() will reset lastField and lastFieldNumber.
+- addField(lastFieldNumber, lastField.build());
+- }
++ private Field.Builder getFieldBuilder(int number) {
+ if (number == 0) {
+ return null;
+ } else {
+- final Field existing = fields.get(number);
+- lastFieldNumber = number;
+- lastField = Field.newBuilder();
+- if (existing != null) {
+- lastField.mergeFrom(existing);
++ Field.Builder builder = fieldBuilders.get(number);
++ if (builder == null) {
++ builder = Field.newBuilder();
++ fieldBuilders.put(number, builder);
+ }
+- return lastField;
++ return builder;
+ }
+ }
+
+ /**
+ * Build the {@link UnknownFieldSet} and return it.
+- *
+- * <p>Once {@code build()} has been called, the {@code Builder} will no longer be usable.
+- * Calling any method after {@code build()} will result in undefined behavior and can cause a
+- * {@code NullPointerException} to be thrown.
+ */
+ @Override
+ public UnknownFieldSet build() {
+- getFieldBuilder(0); // Force lastField to be built.
+- final UnknownFieldSet result;
+- if (fields.isEmpty()) {
++ UnknownFieldSet result;
++ if (fieldBuilders.isEmpty()) {
+ result = getDefaultInstance();
+ } else {
+- Map<Integer, Field> descendingFields = null;
+- descendingFields =
+- Collections.unmodifiableMap(((TreeMap<Integer, Field>) fields).descendingMap());
+- result = new UnknownFieldSet(Collections.unmodifiableMap(fields), descendingFields);
++ TreeMap<Integer, Field> fields = new TreeMap<>();
++ for (Map.Entry<Integer, Field.Builder> entry : fieldBuilders.entrySet()) {
++ fields.put(entry.getKey(), entry.getValue().build());
++ }
++ result = new UnknownFieldSet(fields);
+ }
+- fields = null;
+ return result;
+ }
+
+@@ -378,11 +353,13 @@ public final class UnknownFieldSet implements MessageLite {
+
+ @Override
+ public Builder clone() {
+- getFieldBuilder(0); // Force lastField to be built.
+- Map<Integer, Field> descendingFields = null;
+- descendingFields =
+- Collections.unmodifiableMap(((TreeMap<Integer, Field>) fields).descendingMap());
+- return UnknownFieldSet.newBuilder().mergeFrom(new UnknownFieldSet(fields, descendingFields));
++ Builder clone = UnknownFieldSet.newBuilder();
++ for (Map.Entry<Integer, Field.Builder> entry : fieldBuilders.entrySet()) {
++ Integer key = entry.getKey();
++ Field.Builder value = entry.getValue();
++ clone.fieldBuilders.put(key, value.clone());
++ }
++ return clone;
+ }
+
+ @Override
+@@ -390,31 +367,24 @@ public final class UnknownFieldSet implements MessageLite {
+ return UnknownFieldSet.getDefaultInstance();
+ }
+
+- private void reinitialize() {
+- fields = Collections.emptyMap();
+- lastFieldNumber = 0;
+- lastField = null;
+- }
+-
+ /** Reset the builder to an empty set. */
+ @Override
+ public Builder clear() {
+- reinitialize();
++ fieldBuilders = new TreeMap<>();
+ return this;
+ }
+
+- /** Clear fields from the set with a given field number. */
+- public Builder clearField(final int number) {
+- if (number == 0) {
+- throw new IllegalArgumentException("Zero is not a valid field number.");
+- }
+- if (lastField != null && lastFieldNumber == number) {
+- // Discard this.
+- lastField = null;
+- lastFieldNumber = 0;
++ /**
++ * Clear fields from the set with a given field number.
++ *
++ * @throws IllegalArgumentException if number is not positive
++ */
++ public Builder clearField(int number) {
++ if (number <= 0) {
++ throw new IllegalArgumentException(number + " is not a valid field number.");
+ }
+- if (fields.containsKey(number)) {
+- fields.remove(number);
++ if (fieldBuilders.containsKey(number)) {
++ fieldBuilders.remove(number);
+ }
+ return this;
+ }
+@@ -423,9 +393,9 @@ public final class UnknownFieldSet implements MessageLite {
+ * Merge the fields from {@code other} into this set. If a field number exists in both sets,
+ * {@code other}'s values for that field will be appended to the values in this set.
+ */
+- public Builder mergeFrom(final UnknownFieldSet other) {
++ public Builder mergeFrom(UnknownFieldSet other) {
+ if (other != getDefaultInstance()) {
+- for (final Map.Entry<Integer, Field> entry : other.fields.entrySet()) {
++ for (Map.Entry<Integer, Field> entry : other.fields.entrySet()) {
+ mergeField(entry.getKey(), entry.getValue());
+ }
+ }
+@@ -435,10 +405,12 @@ public final class UnknownFieldSet implements MessageLite {
+ /**
+ * Add a field to the {@code UnknownFieldSet}. If a field with the same number already exists,
+ * the two are merged.
++ *
++ * @throws IllegalArgumentException if number is not positive
+ */
+- public Builder mergeField(final int number, final Field field) {
+- if (number == 0) {
+- throw new IllegalArgumentException("Zero is not a valid field number.");
++ public Builder mergeField(int number, final Field field) {
++ if (number <= 0) {
++ throw new IllegalArgumentException(number + " is not a valid field number.");
+ }
+ if (hasField(number)) {
+ getFieldBuilder(number).mergeFrom(field);
+@@ -454,10 +426,12 @@ public final class UnknownFieldSet implements MessageLite {
+ /**
+ * Convenience method for merging a new field containing a single varint value. This is used in
+ * particular when an unknown enum value is encountered.
++ *
++ * @throws IllegalArgumentException if number is not positive
+ */
+- public Builder mergeVarintField(final int number, final int value) {
+- if (number == 0) {
+- throw new IllegalArgumentException("Zero is not a valid field number.");
++ public Builder mergeVarintField(int number, int value) {
++ if (number <= 0) {
++ throw new IllegalArgumentException(number + " is not a valid field number.");
+ }
+ getFieldBuilder(number).addVarint(value);
+ return this;
+@@ -467,40 +441,33 @@ public final class UnknownFieldSet implements MessageLite {
+ * Convenience method for merging a length-delimited field.
+ *
+ * <p>For use by generated code only.
++ *
++ * @throws IllegalArgumentException if number is not positive
+ */
+- public Builder mergeLengthDelimitedField(final int number, final ByteString value) {
+- if (number == 0) {
+- throw new IllegalArgumentException("Zero is not a valid field number.");
++ public Builder mergeLengthDelimitedField(int number, ByteString value) {
++ if (number <= 0) {
++ throw new IllegalArgumentException(number + " is not a valid field number.");
+ }
+ getFieldBuilder(number).addLengthDelimited(value);
+ return this;
+ }
+
+ /** Check if the given field number is present in the set. */
+- public boolean hasField(final int number) {
+- if (number == 0) {
+- throw new IllegalArgumentException("Zero is not a valid field number.");
+- }
+- return number == lastFieldNumber || fields.containsKey(number);
++ public boolean hasField(int number) {
++ return fieldBuilders.containsKey(number);
+ }
+
+ /**
+ * Add a field to the {@code UnknownFieldSet}. If a field with the same number already exists,
+ * it is removed.
++ *
++ * @throws IllegalArgumentException if number is not positive
+ */
+- public Builder addField(final int number, final Field field) {
+- if (number == 0) {
+- throw new IllegalArgumentException("Zero is not a valid field number.");
+- }
+- if (lastField != null && lastFieldNumber == number) {
+- // Discard this.
+- lastField = null;
+- lastFieldNumber = 0;
++ public Builder addField(int number, Field field) {
++ if (number <= 0) {
++ throw new IllegalArgumentException(number + " is not a valid field number.");
+ }
+- if (fields.isEmpty()) {
+- fields = new TreeMap<Integer, Field>();
+- }
+- fields.put(number, field);
++ fieldBuilders.put(number, Field.newBuilder(field));
+ return this;
+ }
+
+@@ -509,15 +476,18 @@ public final class UnknownFieldSet implements MessageLite {
+ * changes may or may not be reflected in this map.
+ */
+ public Map<Integer, Field> asMap() {
+- getFieldBuilder(0); // Force lastField to be built.
++ TreeMap<Integer, Field> fields = new TreeMap<>();
++ for (Map.Entry<Integer, Field.Builder> entry : fieldBuilders.entrySet()) {
++ fields.put(entry.getKey(), entry.getValue().build());
++ }
+ return Collections.unmodifiableMap(fields);
+ }
+
+ /** Parse an entire message from {@code input} and merge its fields into this set. */
+ @Override
+- public Builder mergeFrom(final CodedInputStream input) throws IOException {
++ public Builder mergeFrom(CodedInputStream input) throws IOException {
+ while (true) {
+- final int tag = input.readTag();
++ int tag = input.readTag();
+ if (tag == 0 || !mergeFieldFrom(tag, input)) {
+ break;
+ }
+@@ -531,8 +501,8 @@ public final class UnknownFieldSet implements MessageLite {
+ * @param tag The field's tag number, which was already parsed.
+ * @return {@code false} if the tag is an end group tag.
+ */
+- public boolean mergeFieldFrom(final int tag, final CodedInputStream input) throws IOException {
+- final int number = WireFormat.getTagFieldNumber(tag);
++ public boolean mergeFieldFrom(int tag, CodedInputStream input) throws IOException {
++ int number = WireFormat.getTagFieldNumber(tag);
+ switch (WireFormat.getTagWireType(tag)) {
+ case WireFormat.WIRETYPE_VARINT:
+ getFieldBuilder(number).addVarint(input.readInt64());
+@@ -544,7 +514,7 @@ public final class UnknownFieldSet implements MessageLite {
+ getFieldBuilder(number).addLengthDelimited(input.readBytes());
+ return true;
+ case WireFormat.WIRETYPE_START_GROUP:
+- final Builder subBuilder = newBuilder();
++ Builder subBuilder = newBuilder();
+ input.readGroup(number, subBuilder, ExtensionRegistry.getEmptyRegistry());
+ getFieldBuilder(number).addGroup(subBuilder.build());
+ return true;
+@@ -563,15 +533,15 @@ public final class UnknownFieldSet implements MessageLite {
+ * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}.
+ */
+ @Override
+- public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
++ public Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException {
+ try {
+- final CodedInputStream input = data.newCodedInput();
++ CodedInputStream input = data.newCodedInput();
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return this;
+- } catch (final InvalidProtocolBufferException e) {
++ } catch (InvalidProtocolBufferException e) {
+ throw e;
+- } catch (final IOException e) {
++ } catch (IOException e) {
+ throw new RuntimeException(
+ "Reading from a ByteString threw an IOException (should never happen).", e);
+ }
+@@ -582,15 +552,15 @@ public final class UnknownFieldSet implements MessageLite {
+ * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}.
+ */
+ @Override
+- public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
++ public Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException {
+ try {
+- final CodedInputStream input = CodedInputStream.newInstance(data);
++ CodedInputStream input = CodedInputStream.newInstance(data);
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return this;
+- } catch (final InvalidProtocolBufferException e) {
++ } catch (InvalidProtocolBufferException e) {
+ throw e;
+- } catch (final IOException e) {
++ } catch (IOException e) {
+ throw new RuntimeException(
+ "Reading from a byte array threw an IOException (should never happen).", e);
+ }
+@@ -601,8 +571,8 @@ public final class UnknownFieldSet implements MessageLite {
+ * This is just a small wrapper around {@link #mergeFrom(CodedInputStream)}.
+ */
+ @Override
+- public Builder mergeFrom(final InputStream input) throws IOException {
+- final CodedInputStream codedInput = CodedInputStream.newInstance(input);
++ public Builder mergeFrom(InputStream input) throws IOException {
++ CodedInputStream codedInput = CodedInputStream.newInstance(input);
+ mergeFrom(codedInput);
+ codedInput.checkLastTagWas(0);
+ return this;
+@@ -610,12 +580,12 @@ public final class UnknownFieldSet implements MessageLite {
+
+ @Override
+ public boolean mergeDelimitedFrom(InputStream input) throws IOException {
+- final int firstByte = input.read();
++ int firstByte = input.read();
+ if (firstByte == -1) {
+ return false;
+ }
+- final int size = CodedInputStream.readRawVarint32(firstByte, input);
+- final InputStream limitedInput = new LimitedInputStream(input, size);
++ int size = CodedInputStream.readRawVarint32(firstByte, input);
++ InputStream limitedInput = new LimitedInputStream(input, size);
+ mergeFrom(limitedInput);
+ return true;
+ }
+@@ -644,7 +614,7 @@ public final class UnknownFieldSet implements MessageLite {
+ @Override
+ public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException {
+ try {
+- final CodedInputStream input = CodedInputStream.newInstance(data, off, len);
++ CodedInputStream input = CodedInputStream.newInstance(data, off, len);
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return this;
+@@ -718,7 +688,7 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ /** Construct a new {@link Builder} and initialize it to a copy of {@code copyFrom}. */
+- public static Builder newBuilder(final Field copyFrom) {
++ public static Builder newBuilder(Field copyFrom) {
+ return newBuilder().mergeFrom(copyFrom);
+ }
+
+@@ -758,7 +728,7 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ @Override
+- public boolean equals(final Object other) {
++ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+@@ -785,7 +755,7 @@ public final class UnknownFieldSet implements MessageLite {
+ public ByteString toByteString(int fieldNumber) {
+ try {
+ // TODO(lukes): consider caching serialized size in a volatile long
+- final ByteString.CodedBuilder out =
++ ByteString.CodedBuilder out =
+ ByteString.newCodedBuilder(getSerializedSize(fieldNumber));
+ writeTo(fieldNumber, out.getCodedOutput());
+ return out.build();
+@@ -796,40 +766,40 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ /** Serializes the field, including field number, and writes it to {@code output}. */
+- public void writeTo(final int fieldNumber, final CodedOutputStream output) throws IOException {
+- for (final long value : varint) {
++ public void writeTo(int fieldNumber, CodedOutputStream output) throws IOException {
++ for (long value : varint) {
+ output.writeUInt64(fieldNumber, value);
+ }
+- for (final int value : fixed32) {
++ for (int value : fixed32) {
+ output.writeFixed32(fieldNumber, value);
+ }
+- for (final long value : fixed64) {
++ for (long value : fixed64) {
+ output.writeFixed64(fieldNumber, value);
+ }
+- for (final ByteString value : lengthDelimited) {
++ for (ByteString value : lengthDelimited) {
+ output.writeBytes(fieldNumber, value);
+ }
+- for (final UnknownFieldSet value : group) {
++ for (UnknownFieldSet value : group) {
+ output.writeGroup(fieldNumber, value);
+ }
+ }
+
+ /** Get the number of bytes required to encode this field, including field number. */
+- public int getSerializedSize(final int fieldNumber) {
++ public int getSerializedSize(int fieldNumber) {
+ int result = 0;
+- for (final long value : varint) {
++ for (long value : varint) {
+ result += CodedOutputStream.computeUInt64Size(fieldNumber, value);
+ }
+- for (final int value : fixed32) {
++ for (int value : fixed32) {
+ result += CodedOutputStream.computeFixed32Size(fieldNumber, value);
+ }
+- for (final long value : fixed64) {
++ for (long value : fixed64) {
+ result += CodedOutputStream.computeFixed64Size(fieldNumber, value);
+ }
+- for (final ByteString value : lengthDelimited) {
++ for (ByteString value : lengthDelimited) {
+ result += CodedOutputStream.computeBytesSize(fieldNumber, value);
+ }
+- for (final UnknownFieldSet value : group) {
++ for (UnknownFieldSet value : group) {
+ result += CodedOutputStream.computeGroupSize(fieldNumber, value);
+ }
+ return result;
+@@ -839,15 +809,15 @@ public final class UnknownFieldSet implements MessageLite {
+ * Serializes the field, including field number, and writes it to {@code output}, using {@code
+ * MessageSet} wire format.
+ */
+- public void writeAsMessageSetExtensionTo(final int fieldNumber, final CodedOutputStream output)
++ public void writeAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output)
+ throws IOException {
+- for (final ByteString value : lengthDelimited) {
++ for (ByteString value : lengthDelimited) {
+ output.writeRawMessageSetExtension(fieldNumber, value);
+ }
+ }
+
+ /** Serializes the field, including field number, and writes it to {@code writer}. */
+- void writeTo(final int fieldNumber, final Writer writer) throws IOException {
++ void writeTo(int fieldNumber, Writer writer) throws IOException {
+ writer.writeInt64List(fieldNumber, varint, false);
+ writer.writeFixed32List(fieldNumber, fixed32, false);
+ writer.writeFixed64List(fieldNumber, fixed64, false);
+@@ -872,7 +842,7 @@ public final class UnknownFieldSet implements MessageLite {
+ * Serializes the field, including field number, and writes it to {@code writer}, using {@code
+ * MessageSet} wire format.
+ */
+- private void writeAsMessageSetExtensionTo(final int fieldNumber, final Writer writer)
++ private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer)
+ throws IOException {
+ if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
+ // Write in descending field order.
+@@ -882,7 +852,7 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+ } else {
+ // Write in ascending field order.
+- for (final ByteString value : lengthDelimited) {
++ for (ByteString value : lengthDelimited) {
+ writer.writeMessageSetItem(fieldNumber, value);
+ }
+ }
+@@ -892,9 +862,9 @@ public final class UnknownFieldSet implements MessageLite {
+ * Get the number of bytes required to encode this field, including field number, using {@code
+ * MessageSet} wire format.
+ */
+- public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) {
++ public int getSerializedSizeAsMessageSetExtension(int fieldNumber) {
+ int result = 0;
+- for (final ByteString value : lengthDelimited) {
++ for (ByteString value : lengthDelimited) {
+ result += CodedOutputStream.computeRawMessageSetExtensionSize(fieldNumber, value);
+ }
+ return result;
+@@ -912,52 +882,85 @@ public final class UnknownFieldSet implements MessageLite {
+ * <p>Use {@link Field#newBuilder()} to construct a {@code Builder}.
+ */
+ public static final class Builder {
+- // This constructor should never be called directly (except from 'create').
+- private Builder() {}
++ // This constructor should only be called directly from 'create' and 'clone'.
++ private Builder() {
++ result = new Field();
++ }
+
+ private static Builder create() {
+ Builder builder = new Builder();
+- builder.result = new Field();
+ return builder;
+ }
+
+ private Field result;
+
++ @Override
++ public Builder clone() {
++ Field copy = new Field();
++ if (result.varint == null) {
++ copy.varint = null;
++ } else {
++ copy.varint = new ArrayList<>(result.varint);
++ }
++ if (result.fixed32 == null) {
++ copy.fixed32 = null;
++ } else {
++ copy.fixed32 = new ArrayList<>(result.fixed32);
++ }
++ if (result.fixed64 == null) {
++ copy.fixed64 = null;
++ } else {
++ copy.fixed64 = new ArrayList<>(result.fixed64);
++ }
++ if (result.lengthDelimited == null) {
++ copy.lengthDelimited = null;
++ } else {
++ copy.lengthDelimited = new ArrayList<>(result.lengthDelimited);
++ }
++ if (result.group == null) {
++ copy.group = null;
++ } else {
++ copy.group = new ArrayList<>(result.group);
++ }
++
++ Builder clone = new Builder();
++ clone.result = copy;
++ return clone;
++ }
++
+ /**
+- * Build the field. After {@code build()} has been called, the {@code Builder} is no longer
+- * usable. Calling any other method will result in undefined behavior and can cause a {@code
+- * NullPointerException} to be thrown.
++ * Build the field.
+ */
+ public Field build() {
++ Field built = new Field();
+ if (result.varint == null) {
+- result.varint = Collections.emptyList();
++ built.varint = Collections.emptyList();
+ } else {
+- result.varint = Collections.unmodifiableList(result.varint);
++ built.varint = Collections.unmodifiableList(new ArrayList<>(result.varint));
+ }
+ if (result.fixed32 == null) {
+- result.fixed32 = Collections.emptyList();
++ built.fixed32 = Collections.emptyList();
+ } else {
+- result.fixed32 = Collections.unmodifiableList(result.fixed32);
++ built.fixed32 = Collections.unmodifiableList(new ArrayList<>(result.fixed32));
+ }
+ if (result.fixed64 == null) {
+- result.fixed64 = Collections.emptyList();
++ built.fixed64 = Collections.emptyList();
+ } else {
+- result.fixed64 = Collections.unmodifiableList(result.fixed64);
++ built.fixed64 = Collections.unmodifiableList(new ArrayList<>(result.fixed64));
+ }
+ if (result.lengthDelimited == null) {
+- result.lengthDelimited = Collections.emptyList();
++ built.lengthDelimited = Collections.emptyList();
+ } else {
+- result.lengthDelimited = Collections.unmodifiableList(result.lengthDelimited);
++ built.lengthDelimited = Collections.unmodifiableList(
++ new ArrayList<>(result.lengthDelimited));
+ }
+ if (result.group == null) {
+- result.group = Collections.emptyList();
++ built.group = Collections.emptyList();
+ } else {
+- result.group = Collections.unmodifiableList(result.group);
++ built.group = Collections.unmodifiableList(new ArrayList<>(result.group));
+ }
+
+- final Field returnMe = result;
+- result = null;
+- return returnMe;
++ return built;
+ }
+
+ /** Discard the field's contents. */
+@@ -970,7 +973,7 @@ public final class UnknownFieldSet implements MessageLite {
+ * Merge the values in {@code other} into this field. For each list of values, {@code other}'s
+ * values are append to the ones in this field.
+ */
+- public Builder mergeFrom(final Field other) {
++ public Builder mergeFrom(Field other) {
+ if (!other.varint.isEmpty()) {
+ if (result.varint == null) {
+ result.varint = new ArrayList<Long>();
+@@ -985,19 +988,19 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+ if (!other.fixed64.isEmpty()) {
+ if (result.fixed64 == null) {
+- result.fixed64 = new ArrayList<Long>();
++ result.fixed64 = new ArrayList<>();
+ }
+ result.fixed64.addAll(other.fixed64);
+ }
+ if (!other.lengthDelimited.isEmpty()) {
+ if (result.lengthDelimited == null) {
+- result.lengthDelimited = new ArrayList<ByteString>();
++ result.lengthDelimited = new ArrayList<>();
+ }
+ result.lengthDelimited.addAll(other.lengthDelimited);
+ }
+ if (!other.group.isEmpty()) {
+ if (result.group == null) {
+- result.group = new ArrayList<UnknownFieldSet>();
++ result.group = new ArrayList<>();
+ }
+ result.group.addAll(other.group);
+ }
+@@ -1005,45 +1008,45 @@ public final class UnknownFieldSet implements MessageLite {
+ }
+
+ /** Add a varint value. */
+- public Builder addVarint(final long value) {
++ public Builder addVarint(long value) {
+ if (result.varint == null) {
+- result.varint = new ArrayList<Long>();
++ result.varint = new ArrayList<>();
+ }
+ result.varint.add(value);
+ return this;
+ }
+
+ /** Add a fixed32 value. */
+- public Builder addFixed32(final int value) {
++ public Builder addFixed32(int value) {
+ if (result.fixed32 == null) {
+- result.fixed32 = new ArrayList<Integer>();
++ result.fixed32 = new ArrayList<>();
+ }
+ result.fixed32.add(value);
+ return this;
+ }
+
+ /** Add a fixed64 value. */
+- public Builder addFixed64(final long value) {
++ public Builder addFixed64(long value) {
+ if (result.fixed64 == null) {
+- result.fixed64 = new ArrayList<Long>();
++ result.fixed64 = new ArrayList<>();
+ }
+ result.fixed64.add(value);
+ return this;
+ }
+
+ /** Add a length-delimited value. */
+- public Builder addLengthDelimited(final ByteString value) {
++ public Builder addLengthDelimited(ByteString value) {
+ if (result.lengthDelimited == null) {
+- result.lengthDelimited = new ArrayList<ByteString>();
++ result.lengthDelimited = new ArrayList<>();
+ }
+ result.lengthDelimited.add(value);
+ return this;
+ }
+
+ /** Add an embedded group. */
+- public Builder addGroup(final UnknownFieldSet value) {
++ public Builder addGroup(UnknownFieldSet value) {
+ if (result.group == null) {
+- result.group = new ArrayList<UnknownFieldSet>();
++ result.group = new ArrayList<>();
+ }
+ result.group.add(value);
+ return this;
+diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java
+new file mode 100644
+index 0000000..6ce0fc7
+--- /dev/null
++++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java
+@@ -0,0 +1,78 @@
++// Protocol Buffers - Google's data interchange format
++// Copyright 2008 Google Inc. All rights reserved.
++// https://developers.google.com/protocol-buffers/
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions are
++// met:
++//
++// * Redistributions of source code must retain the above copyright
++// notice, this list of conditions and the following disclaimer.
++// * Redistributions in binary form must reproduce the above
++// copyright notice, this list of conditions and the following disclaimer
++// in the documentation and/or other materials provided with the
++// distribution.
++// * Neither the name of Google Inc. nor the names of its
++// contributors may be used to endorse or promote products derived from
++// this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++package com.google.protobuf;
++
++import static com.google.common.truth.Truth.assertThat;
++
++import java.io.ByteArrayInputStream;
++import java.io.IOException;
++import java.io.InputStream;
++import org.junit.Test;
++import org.junit.runner.RunWith;
++import org.junit.runners.JUnit4;
++
++@RunWith(JUnit4.class)
++public final class UnknownFieldSetPerformanceTest {
++
++ private static byte[] generateBytes(int length) {
++ assertThat(length % 4).isEqualTo(0);
++ byte[] input = new byte[length];
++ for (int i = 0; i < length; i += 4) {
++ input[i] = (byte) 0x08; // field 1, wiretype 0
++ input[i + 1] = (byte) 0x08; // field 1, payload 8
++ input[i + 2] = (byte) 0x20; // field 4, wiretype 0
++ input[i + 3] = (byte) 0x20; // field 4, payload 32
++ }
++ return input;
++ }
++
++ @Test
++ // This is a performance test. Failure here is a timeout.
++ public void testAlternatingFieldNumbers() throws IOException {
++ byte[] input = generateBytes(800000);
++ InputStream in = new ByteArrayInputStream(input);
++ UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder();
++ CodedInputStream codedInput = CodedInputStream.newInstance(in);
++ builder.mergeFrom(codedInput);
++ }
++
++ @Test
++ // This is a performance test. Failure here is a timeout.
++ public void testAddField() {
++ UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder();
++ for (int i = 1; i <= 100000; i++) {
++ UnknownFieldSet.Field field = UnknownFieldSet.Field.newBuilder().addFixed32(i).build();
++ builder.addField(i, field);
++ }
++ UnknownFieldSet fieldSet = builder.build();
++ assertThat(fieldSet.getField(100000).getFixed32List().get(0)).isEqualTo(100000);
++ }
++}
+diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
+index c7eb57c..3e1e928 100644
+--- a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
++++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
+@@ -30,6 +30,9 @@
+
+ package com.google.protobuf;
+
++import static com.google.common.truth.Truth.assertThat;
++import static com.google.common.truth.Truth.assertWithMessage;
++
+ import protobuf_unittest.UnittestProto;
+ import protobuf_unittest.UnittestProto.ForeignEnum;
+ import protobuf_unittest.UnittestProto.TestAllExtensions;
+@@ -39,8 +42,10 @@ import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
+ import protobuf_unittest.UnittestProto.TestPackedExtensions;
+ import protobuf_unittest.UnittestProto.TestPackedTypes;
+ import proto3_unittest.UnittestProto3;
++import java.util.List;
+ import java.util.Arrays;
+ import java.util.Map;
++import org.junit.Assert;
+ import junit.framework.TestCase;
+
+ /**
+@@ -58,7 +63,7 @@ public class UnknownFieldSetTest extends TestCase {
+ unknownFields = emptyMessage.getUnknownFields();
+ }
+
+- UnknownFieldSet.Field getField(String name) {
++ private UnknownFieldSet.Field getField(String name) {
+ Descriptors.FieldDescriptor field = descriptor.findFieldByName(name);
+ assertNotNull(field);
+ return unknownFields.getField(field.getNumber());
+@@ -97,6 +102,161 @@ public class UnknownFieldSetTest extends TestCase {
+
+ // =================================================================
+
++ public void testFieldBuildersAreReusable() {
++ UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder();
++ fieldBuilder.addFixed32(10);
++ UnknownFieldSet.Field first = fieldBuilder.build();
++ UnknownFieldSet.Field second = fieldBuilder.build();
++ fieldBuilder.addFixed32(11);
++ UnknownFieldSet.Field third = fieldBuilder.build();
++
++ assertThat(first).isEqualTo(second);
++ assertThat(first).isNotEqualTo(third);
++ }
++
++ public void testClone() {
++ UnknownFieldSet.Builder unknownSetBuilder = UnknownFieldSet.newBuilder();
++ UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder();
++ fieldBuilder.addFixed32(10);
++ unknownSetBuilder.addField(8, fieldBuilder.build());
++ // necessary to call clone twice to expose the bug
++ UnknownFieldSet.Builder clone1 = unknownSetBuilder.clone();
++ UnknownFieldSet.Builder clone2 = unknownSetBuilder.clone(); // failure is a NullPointerException
++ assertThat(clone1).isNotSameInstanceAs(clone2);
++ }
++
++ public void testClone_lengthDelimited() {
++ UnknownFieldSet.Builder destUnknownFieldSet =
++ UnknownFieldSet.newBuilder()
++ .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build())
++ .addField(
++ 999,
++ UnknownFieldSet.Field.newBuilder()
++ .addLengthDelimited(ByteString.copyFromUtf8("some data"))
++ .addLengthDelimited(ByteString.copyFromUtf8("some more data"))
++ .build());
++ UnknownFieldSet clone = destUnknownFieldSet.clone().build();
++ assertThat(clone.getField(997)).isNotNull();
++ UnknownFieldSet.Field field999 = clone.getField(999);
++ List<ByteString> lengthDelimited = field999.getLengthDelimitedList();
++ assertThat(lengthDelimited.get(0).toStringUtf8()).isEqualTo("some data");
++ assertThat(lengthDelimited.get(1).toStringUtf8()).isEqualTo("some more data");
++
++ UnknownFieldSet clone2 = destUnknownFieldSet.clone().build();
++ assertThat(clone2.getField(997)).isNotNull();
++ UnknownFieldSet.Field secondField = clone2.getField(999);
++ List<ByteString> lengthDelimited2 = secondField.getLengthDelimitedList();
++ assertThat(lengthDelimited2.get(0).toStringUtf8()).isEqualTo("some data");
++ assertThat(lengthDelimited2.get(1).toStringUtf8()).isEqualTo("some more data");
++ }
++
++ public void testReuse() {
++ UnknownFieldSet.Builder builder =
++ UnknownFieldSet.newBuilder()
++ .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build())
++ .addField(
++ 999,
++ UnknownFieldSet.Field.newBuilder()
++ .addLengthDelimited(ByteString.copyFromUtf8("some data"))
++ .addLengthDelimited(ByteString.copyFromUtf8("some more data"))
++ .build());
++
++ UnknownFieldSet fieldSet1 = builder.build();
++ UnknownFieldSet fieldSet2 = builder.build();
++ builder.addField(1000, UnknownFieldSet.Field.newBuilder().addVarint(-90).build());
++ UnknownFieldSet fieldSet3 = builder.build();
++
++ assertThat(fieldSet1).isEqualTo(fieldSet2);
++ assertThat(fieldSet1).isNotEqualTo(fieldSet3);
++ }
++
++ @SuppressWarnings("ModifiedButNotUsed")
++ public void testAddField_zero() {
++ UnknownFieldSet.Field field = getField("optional_int32");
++ try {
++ UnknownFieldSet.newBuilder().addField(0, field);
++ Assert.fail();
++ } catch (IllegalArgumentException expected) {
++ assertThat(expected).hasMessageThat().isEqualTo("0 is not a valid field number.");
++ }
++ }
++
++ @SuppressWarnings("ModifiedButNotUsed")
++ public void testAddField_negative() {
++ UnknownFieldSet.Field field = getField("optional_int32");
++ try {
++ UnknownFieldSet.newBuilder().addField(-2, field);
++ Assert.fail();
++ } catch (IllegalArgumentException expected) {
++ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number.");
++ }
++ }
++
++ @SuppressWarnings("ModifiedButNotUsed")
++ public void testClearField_negative() {
++ try {
++ UnknownFieldSet.newBuilder().clearField(-28);
++ Assert.fail();
++ } catch (IllegalArgumentException expected) {
++ assertThat(expected).hasMessageThat().isEqualTo("-28 is not a valid field number.");
++ }
++ }
++
++ @SuppressWarnings("ModifiedButNotUsed")
++ public void testMergeField_negative() {
++ UnknownFieldSet.Field field = getField("optional_int32");
++ try {
++ UnknownFieldSet.newBuilder().mergeField(-2, field);
++ Assert.fail();
++ } catch (IllegalArgumentException expected) {
++ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number.");
++ }
++ }
++
++ @SuppressWarnings("ModifiedButNotUsed")
++ public void testMergeVarintField_negative() {
++ try {
++ UnknownFieldSet.newBuilder().mergeVarintField(-2, 78);
++ Assert.fail();
++ } catch (IllegalArgumentException expected) {
++ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number.");
++ }
++ }
++
++ @SuppressWarnings("ModifiedButNotUsed")
++ public void testHasField_negative() {
++ assertThat(UnknownFieldSet.newBuilder().hasField(-2)).isFalse();
++ }
++
++ @SuppressWarnings("ModifiedButNotUsed")
++ public void testMergeLengthDelimitedField_negative() {
++ ByteString byteString = ByteString.copyFromUtf8("some data");
++ try {
++ UnknownFieldSet.newBuilder().mergeLengthDelimitedField(-2, byteString);
++ Assert.fail();
++ } catch (IllegalArgumentException expected) {
++ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number.");
++ }
++ }
++
++ public void testAddField() {
++ UnknownFieldSet.Field field = getField("optional_int32");
++ UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder().addField(1, field).build();
++ assertThat(fieldSet.getField(1)).isEqualTo(field);
++ }
++
++ public void testAddField_withReplacement() {
++ UnknownFieldSet.Field first = UnknownFieldSet.Field.newBuilder().addFixed32(56).build();
++ UnknownFieldSet.Field second = UnknownFieldSet.Field.newBuilder().addFixed32(25).build();
++ UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder()
++ .addField(1, first)
++ .addField(1, second)
++ .build();
++ List<Integer> list = fieldSet.getField(1).getFixed32List();
++ assertThat(list).hasSize(1);
++ assertThat(list.get(0)).isEqualTo(25);
++ }
++
+ public void testVarint() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_int32");
+ assertEquals(1, field.getVarintList().size());
+@@ -173,6 +333,15 @@ public class UnknownFieldSetTest extends TestCase {
+ assertEquals("1: 1\n2: 2\n3: 3\n3: 4\n", destination.toString());
+ }
+
++ public void testAsMap() throws Exception {
++ UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder().mergeFrom(unknownFields);
++ Map<Integer, UnknownFieldSet.Field> mapFromBuilder = builder.asMap();
++ assertThat(mapFromBuilder).isNotEmpty();
++ UnknownFieldSet fields = builder.build();
++ Map<Integer, UnknownFieldSet.Field> mapFromFieldSet = fields.asMap();
++ assertThat(mapFromFieldSet).containsExactlyEntriesIn(mapFromBuilder);
++ }
++
+ public void testClear() throws Exception {
+ UnknownFieldSet fields = UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build();
+ assertTrue(fields.asMap().isEmpty());
+diff --git a/java/lite/pom.xml b/java/lite/pom.xml
+index 104c5c1..d095483 100644
+--- a/java/lite/pom.xml
++++ b/java/lite/pom.xml
+@@ -232,7 +232,8 @@
+ <exclude>TestUtil.java</exclude>
+ <exclude>TypeRegistryTest.java</exclude>
+ <exclude>UnknownEnumValueTest.java</exclude>
+- <exclude>UnknownFieldSetLiteTest.java</exclude>
++ <exclude>UnknownFieldSetLiteTest.java</exclude>
++ <exclude>UnknownFieldSetPerformanceTest.java</exclude>
+ <exclude>UnknownFieldSetTest.java</exclude>
+ <exclude>WellKnownTypesTest.java</exclude>
+ <exclude>WireFormatTest.java</exclude>
+--
+2.30.0
+
diff --git a/0007-add-coverage-compile-option.patch b/0007-add-coverage-compile-option.patch
new file mode 100644
index 0000000..3e423f9
--- /dev/null
+++ b/0007-add-coverage-compile-option.patch
@@ -0,0 +1,49 @@
+From c87fadf8be81e48697eca3308981ec3a684ecfcc Mon Sep 17 00:00:00 2001
+From: chengzrz <czrzrichard@gmail.com>
+Date: Wed, 16 Nov 2022 17:47:10 +0800
+Subject: [PATCH] protobuf: add coverage compile option
+
+Type:testcode
+reason:add coverage compile option
+
+Signed-off-by: chengzrz <czrzrichard@gmail.com>
+---
+ configure.ac | 7 +++++++
+ src/Makefile.am | 4 ++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/configure.ac b/configure.ac
+index eb70a76..2ef1668 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -72,6 +72,13 @@ AC_ARG_WITH([protoc],
+ [use the given protoc command instead of building a new one when building tests (useful for cross-compiling)])],
+ [],[with_protoc=no])
+
++AC_ARG_ENABLE([coverage],
++ [AS_HELP_STRING([--enable-coverage],
++ [generate coverage report])],
++ [coverage=yes],[coverage=no])
++
++AM_CONDITIONAL([HAVE_COVERAGE], [test "x$coverage" == "xyes"])
++
+ # Checks for programs.
+ AC_PROG_CC
+ AC_PROG_CXX
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 9af3db1..81d1418 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -21,6 +21,10 @@ endif
+ PROTOBUF_VERSION = 25:0:0
+ PROTOBUF_OPT_FLAG += -Wl,-z,now -fstack-check
+
++if HAVE_COVERAGE
++PROTOBUF_OPT_FLAG += -fprofile-arcs -ftest-coverage
++endif
++
+ if GCC
+ # Turn on all warnings except for sign comparison (we ignore sign comparison
+ # in Google so our code base have tons of such warnings).
+--
+2.26.3
diff --git a/protobuf.spec b/protobuf.spec
index 287ccd9..ea43bab 100644
--- a/protobuf.spec
+++ b/protobuf.spec
@@ -1,34 +1,25 @@
-#needsrootforbuild
-%undefine __cmake_in_source_build
-
-%define _lto_cflags %{nil}
-
# Build -python subpackage
%bcond_without python
# Build -java subpackage
-%ifarch loongarch64
-%bcond_with java
-%else
%bcond_without java
-%endif
+
+#global rcver rc2
Summary: Protocol Buffers - Google's data interchange format
Name: protobuf
Version: 32.1
Release: 12
-License: BSD-3-Clause
+License: BSD
URL: https://github.com/protocolbuffers/protobuf
Source: https://github.com/protocolbuffers/protobuf/releases/download/v%{version}%{?rcver}/%{name}-%{version}%{?rcver}.tar.gz
Source1: protobuf-init.el
-%global so_version 32.1
-Patch9000: 0001-add-secure-compile-option.patch
-Patch9001: 0002-Fix-CC-compiler-support.patch
-Patch9002: 0003-protobuf-add-coverage-compile-option.patch
+Patch9000: 0001-add-secure-compile-option-in-Makefile.patch
+Patch9001: 0002-add-secure-compile-fs-check-in-Makefile.patch
+Patch9003: 0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch
+Patch9006: 0007-add-coverage-compile-option.patch
-BuildRequires: cmake gcc-c++ emacs zlib-devel gmock-devel gtest-devel jsoncpp-devel
-BuildRequires: fdupes pkgconfig python-rpm-macros pkgconfig(zlib) ninja-build
-BuildRequires: abseil-cpp-devel >= 20230802
+BuildRequires: make autoconf automake emacs gcc-c++ libtool pkgconfig zlib-devel
%description
@@ -53,7 +44,6 @@ Summary: Protocol Buffers C++ headers and libraries
Requires: %{name} = %{version}-%{release}
Requires: %{name}-compiler = %{version}-%{release}
Requires: zlib-devel pkgconfig vim-enhanced
-Requires: abseil-cpp-devel >= 20230802
Provides: %{name}-static
Provides: %{name}-vim
Obsoletes: %{name}-static < %{version}
@@ -116,25 +106,15 @@ This package contains Python 3 libraries for Google Protocol Buffers
%package java
Summary: Java Protocol Buffers runtime library
BuildArch: noarch
-BuildRequires: java-devel >= 1.6
-BuildRequires: jpackage-utils
-BuildRequires: maven-local
-BuildRequires: mvn(com.google.code.gson:gson)
-BuildRequires: mvn(com.google.guava:guava)
-BuildRequires: mvn(junit:junit)
-BuildRequires: mvn(org.easymock:easymock)
-BuildRequires: mvn(org.apache.felix:maven-bundle-plugin)
-BuildRequires: mvn(org.apache.maven.plugins:maven-antrun-plugin)
-BuildRequires: mvn(org.apache.maven.plugins:maven-source-plugin)
-BuildRequires: mvn(org.codehaus.mojo:build-helper-maven-plugin)
-BuildRequires: maven-compiler-plugin
-BuildRequires: maven-install-plugin
-BuildRequires: maven-jar-plugin
-BuildRequires: maven-javadoc-plugin
-BuildRequires: maven-release-plugin
-BuildRequires: maven-resources-plugin
-BuildRequires: maven-surefire-plugin
-BuildRequires: maven-antrun-plugin
+BuildRequires: maven-local
+BuildRequires: mvn(com.google.code.gson:gson)
+BuildRequires: mvn(com.google.guava:guava)
+BuildRequires: mvn(junit:junit)
+BuildRequires: mvn(org.apache.felix:maven-bundle-plugin)
+BuildRequires: mvn(org.apache.maven.plugins:maven-antrun-plugin)
+BuildRequires: mvn(org.apache.maven.plugins:maven-source-plugin)
+BuildRequires: mvn(org.codehaus.mojo:build-helper-maven-plugin)
+BuildRequires: mvn(org.easymock:easymock)
Obsoletes: %{name}-javanano < 3.6.0
%description java
@@ -182,18 +162,14 @@ Protocol Buffer BOM POM.
%setup -q -n %{name}-%{version}%{?rcver}
%autopatch -p1
find -name \*.cc -o -name \*.h | xargs chmod -x
-find examples -type f | xargs chmod 644
+chmod 644 examples/*
%if %{with java}
#%pom_remove_dep com.google.truth:truth java/pom.xml
#%pom_remove_dep org.easymock:easymockclassextension java/pom.xml java/*/pom.xml
-#%pom_remove_dep org.easymock:easymockclassextension java/pom.xml java/core/pom.xml java/lite/pom.xml java/util/pom.xml
+%pom_remove_dep org.easymock:easymockclassextension java/pom.xml java/core/pom.xml java/lite/pom.xml java/util/pom.xml
%pom_remove_dep com.google.truth:truth java/pom.xml java/util/pom.xml java/lite/pom.xml java/core/pom.xml
%pom_remove_dep com.google.errorprone:error_prone_annotations java/util/pom.xml
%pom_remove_dep com.google.guava:guava-testlib java/pom.xml java/util/pom.xml
-%pom_remove_dep com.google.j2objc:j2objc-annotations java/util/pom.xml
-
-%pom_remove_plugin org.codehaus.mojo:animal-sniffer-maven-plugin java/pom.xml java/util/pom.xml
-%pom_remove_dep org.mockito:mockito-core java/pom.xml java/core/pom.xml java/lite/pom.xml java/util/pom.xml
# These use easymockclassextension
rm java/core/src/test/java/com/google/protobuf/ServiceTest.java
@@ -230,63 +206,26 @@ mv java/core/src/test/java/com/google/protobuf/DecodeUtf8Test.java \
rm -f src/solaris/libstdc++.la
%build
-%cmake \
- -B build \
- -Dprotobuf_BUILD_EXAMPLES:BOOL=OFF \
- -Dprotobuf_BUILD_LIBPROTOC:BOOL=ON \
- -Dprotobuf_BUILD_SHARED_LIBS:BOOL=ON \
- -Dprotobuf_USE_EXTERNAL_GTEST:BOOL=ON \
- -Dprotobuf_ABSL_PROVIDER=package \
- -Dprotobuf_BUILD_TESTS:BOOL=OFF \
- -DCMAKE_EXE_LINKER_FLAGS="%{build_ldflags}" \
- -DCMAKE_SHARED_LINKER_FLAGS="%{build_ldflags}" \
- -DCMAKE_CXX_FLAGS="%{build_cxxflags} %{?_ld_as_needed_flags}" \
- -DCMAKE_C_COMPILER=%{__cc} \
- -DCMAKE_CXX_COMPILER=%{__cxx} \
- -DCMAKE_SKIP_RPATH=TRUE \
- -G Ninja
-
-%ninja_build -C build
-
-%cmake \
- -B build-static \
- -Dprotobuf_BUILD_EXAMPLES:BOOL=OFF \
- -Dprotobuf_BUILD_LIBPROTOC:BOOL=ON \
- -Dprotobuf_BUILD_SHARED_LIBS:BOOL=OFF \
- -Dprotobuf_USE_EXTERNAL_GTEST:BOOL=ON \
- -Dprotobuf_ABSL_PROVIDER=package \
- -Dprotobuf_BUILD_TESTS:BOOL=OFF \
- -DCMAKE_CXX_FLAGS="-fPIC" \
- -DCMAKE_C_COMPILER=%{__cc} \
- -DCMAKE_CXX_COMPILER=%{__cxx} \
- -DCMAKE_SKIP_RPATH=TRUE \
- -G Ninja
-
-%ninja_build -C build-static
-
-# we have to override LD_LIBRARY_PATH because we eliminated rpath
-export LD_LIBRARY_PATH="${PWD}/build":$LD_LIBRARY_PATH
+iconv -f iso8859-1 -t utf-8 CONTRIBUTORS.txt > CONTRIBUTORS.txt.utf8
+mv CONTRIBUTORS.txt.utf8 CONTRIBUTORS.txt
+export PTHREAD_LIBS="-lpthread"
+./autogen.sh
+%configure
+%make_build CXXFLAGS="%{build_cxxflags} -Wno-error=type-limits"
%if %{with python}
-# Use the just built protoc instead of any
-# system version for python and/or java bindings
-export PROTOC=../build/protoc
pushd python
-CXXFLAGS="%{build_cxxflags}" \
-LDFLAGS="-L../%{_vpath_builddir} -L../%{_vpath_builddir}/third_party/utf8_range %{build_ldflags}" \
%py3_build
popd
%endif
%if %{with java}
-cp build/protoc ./
-%pom_disable_module kotlin java/pom.xml
-%pom_disable_module kotlin-lite java/pom.xml
-%mvn_build -s -- -Dmaven.test.skip=true -f java/pom.xml
+%mvn_build -s -- -f java/pom.xml
%endif
%{_emacs_bytecompile} editors/protobuf-mode.el
+
%check
# Java tests fail on s390x
%ifarch s390x
@@ -294,16 +233,15 @@ fail=0
%else
fail=1
%endif
+%make_build check CXXFLAGS="%{build_cxxflags} -Wno-error=type-limits" || exit $fail
%install
-%ninja_install -C build-static
-%ninja_install -C build
+%make_install %{?_smp_mflags} STRIPBINARIES=no INSTALL="%{__install} -p" CPPROG="cp -p"
+find %{buildroot} -type f -name "*.la" -exec rm -f {} \;
%if %{with python}
pushd python
-CXXFLAGS="%{build_cxxflags}" \
-LDFLAGS="-L../%{_vpath_builddir} -L../%{_vpath_builddir}/third_party/utf8_range %{build_ldflags}" \
#python ./setup.py install --root=%{buildroot} --single-version-externally-managed --record=INSTALLED_FILES --optimize=1
%py3_install
find %{buildroot}%{python3_sitelib} -name \*.py |
@@ -322,40 +260,37 @@ install -p -m 0644 editors/protobuf-mode.elc %{buildroot}%{_emacs_sitelispdir}/%
mkdir -p %{buildroot}%{_emacs_sitestartdir}
install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir}
+%ldconfig_scriptlets
+%ldconfig_scriptlets lite
+%ldconfig_scriptlets compiler
+
%files
-%doc CONTRIBUTORS.txt README.md
+%doc CHANGES.txt CONTRIBUTORS.txt README.md
%license LICENSE
-%{_libdir}/libprotobuf.so.%{so_version}{,.*}
+%{_libdir}/libprotobuf.so.25*
%files compiler
-%{_bindir}/protoc*
-%{_libdir}/libprotoc.so.%{so_version}{,.*}
+%{_bindir}/protoc
+%{_libdir}/libprotoc.so.25*
%{_emacs_sitelispdir}/%{name}/
%{_emacs_sitestartdir}/protobuf-init.el
%license LICENSE
%doc README.md
+
%files devel
%dir %{_includedir}/google
%{_includedir}/google/protobuf/
-%{_includedir}/utf8_range.h
-%{_includedir}/utf8_validity.h
%{_libdir}/libprotobuf.so
%{_libdir}/libprotoc.so
%{_libdir}/pkgconfig/protobuf.pc
-%{_libdir}/pkgconfig/utf8_range.pc
%doc examples/add_person.cc examples/addressbook.proto examples/list_people.cc examples/Makefile examples/README.md
%{_libdir}/libprotobuf.a
%{_libdir}/libprotoc.a
%{_datadir}/vim/vimfiles/syntax/proto.vim
-%{_libdir}/cmake/utf8_range
-%{_libdir}/cmake/protobuf
-%{_libdir}/libutf8_range.a
-%{_libdir}/libutf8_validity.a
-%{_includedir}/java/core/src/main/java/com/google/protobuf/java_features.proto
%files lite
-%{_libdir}/libprotobuf-lite.so.%{so_version}{,.*}
+%{_libdir}/libprotobuf-lite.so.25*
%files lite-devel
%{_libdir}/libprotobuf-lite.so
@@ -366,8 +301,8 @@ install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir}
%files -n python%{python3_pkgversion}-protobuf
%dir %{python3_sitelib}/google
%{python3_sitelib}/google/protobuf/
-%{python3_sitelib}/%{name}-*-py3.*.egg-info/
-%{python3_sitelib}/%{name}-*-py3.*-nspkg.pth
+%{python3_sitelib}/protobuf-%{version}%{?rcver}-py3.*.egg-info/
+%{python3_sitelib}/protobuf-%{version}%{?rcver}-py3.*-nspkg.pth
%doc python/README.md
%doc examples/add_person.py examples/list_people.py examples/addressbook.proto
%endif
@@ -377,7 +312,6 @@ install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir}
%doc examples/AddPerson.java examples/ListPeople.java
%doc java/README.md
%license LICENSE
-%{_includedir}/java/core/src/main/java/com/google/protobuf/java_features.proto
%files java-util -f .mfiles-protobuf-java-util
@@ -401,86 +335,20 @@ install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir}
- SUG:NA
- DESC: update
-* Thu June 26 2025 zhongtao <zhongtao17@huawei.com> - 25.1-12
+* Fri June 27 2025 zhongtao <zhongtao17@huawei.com> - 3.14.0-9
- Type:bugfix
- ID:NA
- SUG:NA
-- DESC: append fix CVE-2025-4565
+- DESC: fix CVE-2025-4565
-* Wed Jun 11 2025 Dongxing Wang <dongxing.wang_a@thundersoft.com> - 25.1-11
-- Type:bugfix
-- CVE:NA
-- SUG:NA
-- DESC: revert:distinguish between statically and dynamically compiled cmake dir to prevent BEP binary differences
+* Wed Dec 06 2023 konglidong <konglidong@uniontech.com> - 3.14.0-8
+- obsolets protobuf2 for fix install conflict
-* Thu May 15 2025 zhongtao <zhongtao17@huawei.com> - 25.1-10
-- Type:bugfix
-- CVE:NA
-- SUG:NA
-- DESC: distinguish between statically and dynamically compiled cmake dir to prevent BEP binary differences
-
-* Fri May 09 2025 zhongtao <zhongtao17@huawei.com> - 25.1-9
-- Type:bugfix
-- ID:NA
-- SUG:NA
-- DESC: distinguish between statically and dynamically compiled pc files to prevent BEP binary differences
-
-* Thu Nov 14 2024 Funda Wang <fundawang@yeah.net> - 25.1-8
-- adopt to new cmake macro
-
-* Wed Sep 25 2024 zhangxianting <zhangxianting@uniontech.com> - 25.1-7
-- Type:bugfix
-- ID:NA
-- SUG:NA
-- DESC: append fix CVE-2024-7254
-
-* Thu Sep 19 2024 zhangxianting <zhangxianting@uniontech.com> - 25.1-6
-- Type:bugfix
-- ID:NA
-- SUG:NA
-- DESC: fix CVE-2024-7254
-
-* Mon Aug 05 2024 zhongtao <zhongtao17@huawei.com> - 25.1-5
-- Type:bugfix
-- ID:NA
-- SUG:NA
-- DESC: bugfix for devel package packaging file differences
-
-* Thu Jul 25 2024 zhongtao <zhongtao17@huawei.com> - 25.1-4
-- Type:bugfix
-- ID:NA
-- SUG:NA
-- DESC: add coverage compile option
-
-* Mon Apr 15 2024 Wenlong Zhang <zhangwenlong@loongson.cn> - 25.1-4
-- disable java for loongarch64
-
-* Tue Apr 09 2024 zhongtao <zhongtao17@huawei.com> - 25.1-3
-- Type:bugfix
-- ID:NA
-- SUG:NA
-- DESC: add secure complie option and code improve
-
-* Wed Mar 20 2024 wangqiang <wangqiang1@kylinos.cn> - 25.1-2
-- Support package build with clang
-
-* Wed Jan 10 2024 zhongtao <zhongtao17@huawei.com> - 25.1-1
-- Type:upgrade
-- ID:NA
-- SUG:NA
-- DESC: update to 25.1
-
-* Wed Dec 06 2023 konglidong <konglidong@uniontech.com> - 3.19.6-2
+* Mon Nov 21 2022 chengzeruizhi <chengzeruizhi@huawei.com> - 3.14.0-7
- Type:enhancement
-- ID:NA
-- SUG:NA
-- DESC: obsolets protobuf2 for fix install conflict
-
-* Mon Jul 17 2023 zhongtao <zhongtao17@huawei.com> - 3.19.6-1
-- Type:upgrade
-- ID:NA
-- SUG:NA
-- DESC: update to 3.19.6
+- ID:NA
+- SUG:NA
+- DESC: add compile option for coverage
* Tue Oct 18 2022 chengzeruizhi <chengzeruizhi@huawei.com> - 3.14.0-6
- Type:bugfix