diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7a8f9ba70cf96..ea004a6b6496e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -86,7 +86,7 @@ if (protobuf_BUILD_SHARED_LIBS)
endif ()
# Version metadata
-set(protobuf_VERSION_STRING "6.31.0")
+set(protobuf_VERSION_STRING "6.31.1")
set(protobuf_DESCRIPTION "Protocol Buffers")
set(protobuf_CONTACT "protobuf@googlegroups.com")
diff --git a/MODULE.bazel b/MODULE.bazel
index 44fcddd9e3d77..b1e4a5440a5f3 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -3,7 +3,7 @@
module(
name = "protobuf",
- version = "31.0", # Automatically updated on release
+ version = "31.1", # Automatically updated on release
compatibility_level = 1,
repo_name = "com_google_protobuf",
)
diff --git a/Protobuf.podspec b/Protobuf.podspec
index b19cecccbc987..55c973c739644 100644
--- a/Protobuf.podspec
+++ b/Protobuf.podspec
@@ -5,7 +5,7 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
- s.version = '4.31.0'
+ s.version = '4.31.1'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/protocolbuffers/protobuf'
s.license = 'BSD-3-Clause'
diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index b79d65f8d5607..2ea6254af3806 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -5,7 +5,7 @@
Codestin Search App
Tools for Protocol Buffers - Google's data interchange format.
See project site for more info.
- 3.31.0
+ 3.31.1
Google Inc.
protobuf-packages
https://github.com/protocolbuffers/protobuf/blob/main/LICENSE
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index c654139f3aaac..1bf9812f67fc6 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -5,7 +5,7 @@
C# runtime library for Protocol Buffers - Google's data interchange format.
Copyright 2015, Google Inc.
Google Protocol Buffers
- 3.31.0
+ 3.31.1
10.0
Google Inc.
netstandard1.1;netstandard2.0;net45;net50
diff --git a/editions/generated_files_test.cc b/editions/generated_files_test.cc
index debe06424c4fa..cf9ff80f1a50a 100644
--- a/editions/generated_files_test.cc
+++ b/editions/generated_files_test.cc
@@ -12,6 +12,7 @@
#include "editions/golden/test_messages_proto2_editions.pb.h"
#include "editions/golden/test_messages_proto3_editions.pb.h"
#include "editions/proto/test_editions_default_features.pb.h"
+#include "google/protobuf/internal_feature_helper.h"
#include "google/protobuf/test_textproto.h"
// These tests provide some basic minimal coverage that protos work as expected.
diff --git a/java/bom/pom.xml b/java/bom/pom.xml
index de1e2aed5cda3..ca5fe44af1f19 100644
--- a/java/bom/pom.xml
+++ b/java/bom/pom.xml
@@ -4,7 +4,7 @@
com.google.protobuf
protobuf-bom
- 4.31.0
+ 4.31.1
pom
Protocol Buffers [BOM]
diff --git a/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java b/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java
index 14d1d0764a61c..9695f847cd4ff 100644
--- a/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java
+++ b/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java
@@ -28,7 +28,7 @@ public enum RuntimeDomain {
public static final RuntimeDomain OSS_DOMAIN = RuntimeDomain.PUBLIC;
public static final int OSS_MAJOR = 4;
public static final int OSS_MINOR = 31;
- public static final int OSS_PATCH = 0;
+ public static final int OSS_PATCH = 1;
public static final String OSS_SUFFIX = "";
public static final RuntimeDomain DOMAIN = OSS_DOMAIN;
diff --git a/java/kotlin/pom.xml b/java/kotlin/pom.xml
index 471a07a5ea968..82dd453578378 100644
--- a/java/kotlin/pom.xml
+++ b/java/kotlin/pom.xml
@@ -4,7 +4,7 @@
com.google.protobuf
protobuf-parent
- 4.31.0
+ 4.31.1
protobuf-kotlin
diff --git a/java/pom.xml b/java/pom.xml
index b03a684578dd7..53f198297383c 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -4,7 +4,7 @@
com.google.protobuf
protobuf-parent
- 4.31.0
+ 4.31.1
pom
Protocol Buffers [Parent]
diff --git a/java/protoc/pom.xml b/java/protoc/pom.xml
index 9544a18d3301e..d645e928c9c28 100644
--- a/java/protoc/pom.xml
+++ b/java/protoc/pom.xml
@@ -8,7 +8,7 @@
com.google.protobuf
protoc
- 4.31.0
+ 4.31.1
pom
Protobuf Compiler
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index d52d31a705e3f..e8eb30388b02c 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -32,7 +32,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
-#define PHP_PROTOBUF_VERSION "4.31.0"
+#define PHP_PROTOBUF_VERSION "4.31.1"
// ptr -> PHP object cache. This is a weak map that caches lazily-created
// wrapper objects around upb types:
diff --git a/protobuf_version.bzl b/protobuf_version.bzl
index 1b62969998183..68bad21034830 100644
--- a/protobuf_version.bzl
+++ b/protobuf_version.bzl
@@ -1,7 +1,7 @@
""" Contains version numbers to be used in other bzl files """
-PROTOC_VERSION = "31.0"
-PROTOBUF_JAVA_VERSION = "4.31.0"
-PROTOBUF_PYTHON_VERSION = "6.31.0"
-PROTOBUF_PHP_VERSION = "4.31.0"
-PROTOBUF_RUBY_VERSION = "4.31.0"
-PROTOBUF_RUST_VERSION = "4.31.0"
+PROTOC_VERSION = "31.1"
+PROTOBUF_JAVA_VERSION = "4.31.1"
+PROTOBUF_PYTHON_VERSION = "6.31.1"
+PROTOBUF_PHP_VERSION = "4.31.1"
+PROTOBUF_RUBY_VERSION = "4.31.1"
+PROTOBUF_RUST_VERSION = "4.31.1"
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index 38a0c6dbd50a0..d41e5bf38500b 100755
--- a/python/google/protobuf/__init__.py
+++ b/python/google/protobuf/__init__.py
@@ -7,4 +7,4 @@
# Copyright 2007 Google Inc. All Rights Reserved.
-__version__ = '6.31.0'
+__version__ = '6.31.1'
diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py
index e2a3de17089ab..dbf848bf31083 100755
--- a/python/google/protobuf/internal/decoder.py
+++ b/python/google/protobuf/internal/decoder.py
@@ -703,7 +703,13 @@ def DecodeRepeatedField(
if value is None:
value = field_dict.setdefault(key, new_default(message))
# Read sub-message.
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError(
+ 'Error parsing message: too many levels of nesting.'
+ )
pos = value.add()._InternalParse(buffer, pos, end, current_depth)
+ current_depth -= 1
# Read end tag.
new_pos = pos+end_tag_len
if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
@@ -722,7 +728,11 @@ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
if value is None:
value = field_dict.setdefault(key, new_default(message))
# Read sub-message.
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
pos = value._InternalParse(buffer, pos, end, current_depth)
+ current_depth -= 1
# Read end tag.
new_pos = pos+end_tag_len
if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
@@ -755,6 +765,11 @@ def DecodeRepeatedField(
if new_pos > end:
raise _DecodeError('Truncated message.')
# Read sub-message.
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError(
+ 'Error parsing message: too many levels of nesting.'
+ )
if (
value.add()._InternalParse(buffer, pos, new_pos, current_depth)
!= new_pos
@@ -762,6 +777,7 @@ def DecodeRepeatedField(
# The only reason _InternalParse would return early is if it
# encountered an end-group tag.
raise _DecodeError('Unexpected end-group tag.')
+ current_depth -= 1
# Predict that the next tag is another copy of the same repeated field.
pos = new_pos + tag_len
if buffer[new_pos:pos] != tag_bytes or new_pos == end:
@@ -781,10 +797,14 @@ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
if new_pos > end:
raise _DecodeError('Truncated message.')
# Read sub-message.
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
if value._InternalParse(buffer, pos, new_pos, current_depth) != new_pos:
# The only reason _InternalParse would return early is if it encountered
# an end-group tag.
raise _DecodeError('Unexpected end-group tag.')
+ current_depth -= 1
return new_pos
return DecodeField
@@ -980,6 +1000,13 @@ def _DecodeFixed32(buffer, pos):
new_pos = pos + 4
return (struct.unpack('= _recursion_limit:
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
data, pos = _DecodeUnknownFieldSet(buffer, pos, end_pos, current_depth)
+ current_depth -= 1
# Check end tag.
if buffer[pos - len(end_tag_bytes) : pos] != end_tag_bytes:
raise _DecodeError('Missing group end tag.')
diff --git a/python/google/protobuf/internal/decoder_test.py b/python/google/protobuf/internal/decoder_test.py
index aa683ad140966..d2bc81b46171b 100644
--- a/python/google/protobuf/internal/decoder_test.py
+++ b/python/google/protobuf/internal/decoder_test.py
@@ -84,6 +84,19 @@ def test_decode_unknown_group_field_nested(self):
self.assertEqual(parsed[0].data[0].data[0].field_number, 3)
self.assertEqual(parsed[0].data[0].data[0].data, 4)
+ def test_decode_unknown_group_field_too_many_levels(self):
+ data = memoryview(b'\023' * 5_000_000)
+ self.assertRaisesRegex(
+ message.DecodeError,
+ 'Error parsing message',
+ decoder._DecodeUnknownField,
+ data,
+ 1,
+ len(data),
+ 1,
+ wire_format.WIRETYPE_START_GROUP,
+ )
+
def test_decode_unknown_mismatched_end_group(self):
self.assertRaisesRegex(
message.DecodeError,
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 1441a49b8584d..ea0c707009a14 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -36,6 +36,7 @@
from google.protobuf.internal import more_extensions_pb2
from google.protobuf.internal import more_messages_pb2
from google.protobuf.internal import packed_field_test_pb2
+from google.protobuf.internal import self_recursive_pb2
from google.protobuf.internal import test_proto3_optional_pb2
from google.protobuf.internal import test_util
from google.protobuf.internal import testing_refleaks
@@ -1431,6 +1432,52 @@ def testMessageClassName(self, message_module):
)
+@testing_refleaks.TestCase
+class TestRecursiveGroup(unittest.TestCase):
+
+ def _MakeRecursiveGroupMessage(self, n):
+ msg = self_recursive_pb2.SelfRecursive()
+ sub = msg
+ for _ in range(n):
+ sub = sub.sub_group
+ sub.i = 1
+ return msg.SerializeToString()
+
+ def testRecursiveGroups(self):
+ recurse_msg = self_recursive_pb2.SelfRecursive()
+ data = self._MakeRecursiveGroupMessage(100)
+ recurse_msg.ParseFromString(data)
+ self.assertTrue(recurse_msg.HasField('sub_group'))
+
+ def testRecursiveGroupsException(self):
+ if api_implementation.Type() != 'python':
+ api_implementation._c_module.SetAllowOversizeProtos(False)
+ recurse_msg = self_recursive_pb2.SelfRecursive()
+ data = self._MakeRecursiveGroupMessage(300)
+ with self.assertRaises(message.DecodeError) as context:
+ recurse_msg.ParseFromString(data)
+ self.assertIn('Error parsing message', str(context.exception))
+ if api_implementation.Type() == 'python':
+ self.assertIn('too many levels of nesting', str(context.exception))
+
+ def testRecursiveGroupsUnknownFields(self):
+ if api_implementation.Type() != 'python':
+ api_implementation._c_module.SetAllowOversizeProtos(False)
+ test_msg = unittest_pb2.TestAllTypes()
+ data = self._MakeRecursiveGroupMessage(300) # unknown to test_msg
+ with self.assertRaises(message.DecodeError) as context:
+ test_msg.ParseFromString(data)
+ self.assertIn(
+ 'Error parsing message',
+ str(context.exception),
+ )
+ if api_implementation.Type() == 'python':
+ self.assertIn('too many levels of nesting', str(context.exception))
+ decoder.SetRecursionLimit(310)
+ test_msg.ParseFromString(data)
+ decoder.SetRecursionLimit(decoder.DEFAULT_RECURSION_LIMIT)
+
+
# Class to test proto2-only features (required, extensions, etc.)
@testing_refleaks.TestCase
class Proto2Test(unittest.TestCase):
@@ -2859,8 +2906,6 @@ def testUnpackedFields(self):
self.assertEqual(golden_data, message.SerializeToString())
-@unittest.skipIf(api_implementation.Type() == 'python',
- 'explicit tests of the C++ implementation')
@testing_refleaks.TestCase
class OversizeProtosTest(unittest.TestCase):
@@ -2877,16 +2922,23 @@ def testSucceedOkSizedProto(self):
msg.ParseFromString(self.GenerateNestedProto(100))
def testAssertOversizeProto(self):
- api_implementation._c_module.SetAllowOversizeProtos(False)
+ if api_implementation.Type() != 'python':
+ api_implementation._c_module.SetAllowOversizeProtos(False)
msg = unittest_pb2.TestRecursiveMessage()
with self.assertRaises(message.DecodeError) as context:
msg.ParseFromString(self.GenerateNestedProto(101))
self.assertIn('Error parsing message', str(context.exception))
def testSucceedOversizeProto(self):
- api_implementation._c_module.SetAllowOversizeProtos(True)
+
+ if api_implementation.Type() == 'python':
+ decoder.SetRecursionLimit(310)
+ else:
+ api_implementation._c_module.SetAllowOversizeProtos(True)
+
msg = unittest_pb2.TestRecursiveMessage()
msg.ParseFromString(self.GenerateNestedProto(101))
+ decoder.SetRecursionLimit(decoder.DEFAULT_RECURSION_LIMIT)
if __name__ == '__main__':
diff --git a/python/google/protobuf/internal/self_recursive.proto b/python/google/protobuf/internal/self_recursive.proto
index 20bc2b4d3eb80..d2a7f004bf947 100644
--- a/python/google/protobuf/internal/self_recursive.proto
+++ b/python/google/protobuf/internal/self_recursive.proto
@@ -12,6 +12,7 @@ package google.protobuf.python.internal;
message SelfRecursive {
SelfRecursive sub = 1;
int32 i = 2;
+ SelfRecursive sub_group = 3 [features.message_encoding = DELIMITED];
}
message IndirectRecursive {
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 94a1121e30264..a714ca00edc05 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -23,6 +23,7 @@
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/dynamic_message.h"
+#include "google/protobuf/internal_feature_helper.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/pyext/descriptor_containers.h"
#include "google/protobuf/pyext/descriptor_pool.h"
diff --git a/python/google/protobuf/runtime_version.py b/python/google/protobuf/runtime_version.py
index 5b923f3baa109..7d69773d99e90 100644
--- a/python/google/protobuf/runtime_version.py
+++ b/python/google/protobuf/runtime_version.py
@@ -29,7 +29,7 @@ class Domain(Enum):
OSS_DOMAIN = Domain.PUBLIC
OSS_MAJOR = 6
OSS_MINOR = 31
-OSS_PATCH = 0
+OSS_PATCH = 1
OSS_SUFFIX = ''
DOMAIN = OSS_DOMAIN
diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec
index d2b91fc11f53c..7a3021017adde 100644
--- a/ruby/google-protobuf.gemspec
+++ b/ruby/google-protobuf.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = "google-protobuf"
- s.version = "4.31.0"
+ s.version = "4.31.1"
git_tag = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag
s.licenses = ["BSD-3-Clause"]
s.summary = "Protocol Buffers"
diff --git a/ruby/pom.xml b/ruby/pom.xml
index b620e6a9c89d0..3f592641f9aa1 100644
--- a/ruby/pom.xml
+++ b/ruby/pom.xml
@@ -9,7 +9,7 @@
com.google.protobuf.jruby
protobuf-jruby
- 4.31.0
+ 4.31.1
Protocol Buffer JRuby native extension
Protocol Buffers are a way of encoding structured data in an efficient yet
@@ -76,7 +76,7 @@
com.google.protobuf
protobuf-java-util
- 4.31.0
+ 4.31.1
org.jruby
diff --git a/src/file_lists.cmake b/src/file_lists.cmake
index c6c6fcf20cd51..e798ad90330bb 100644
--- a/src/file_lists.cmake
+++ b/src/file_lists.cmake
@@ -46,6 +46,7 @@ set(libprotobuf_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_util.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.cc
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/internal_feature_helper.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32.cc
@@ -137,6 +138,7 @@ set(libprotobuf_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/has_bits.h
${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.h
${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.h
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/internal_feature_helper.h
${protobuf_SOURCE_DIR}/src/google/protobuf/internal_visibility.h
${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.h
${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.h
@@ -851,6 +853,7 @@ set(protoc-gen-upb_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_util.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.cc
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/internal_feature_helper.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32.cc
@@ -930,6 +933,7 @@ set(protoc-gen-upb_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/has_bits.h
${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.h
${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.h
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/internal_feature_helper.h
${protobuf_SOURCE_DIR}/src/google/protobuf/internal_visibility.h
${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.h
${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.h
@@ -1020,6 +1024,7 @@ set(protoc-gen-upbdefs_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_util.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.cc
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/internal_feature_helper.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32.cc
@@ -1100,6 +1105,7 @@ set(protoc-gen-upbdefs_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/has_bits.h
${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.h
${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.h
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/internal_feature_helper.h
${protobuf_SOURCE_DIR}/src/google/protobuf/internal_visibility.h
${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.h
${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.h
@@ -1419,6 +1425,7 @@ set(protobuf_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_lite_test.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/has_bits_test.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field_unittest.cc
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/internal_feature_helper_test.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/internal_message_util_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/map_field_test.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/map_test.cc
diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel
index a5a47147fe691..6273bebd6c7a6 100644
--- a/src/google/protobuf/BUILD.bazel
+++ b/src/google/protobuf/BUILD.bazel
@@ -718,6 +718,7 @@ PROTOBUF_HEADERS = [
"descriptor_visitor.h",
"dynamic_message.h",
"feature_resolver.h",
+ "internal_feature_helper.h",
"field_access_listener.h",
"generated_enum_reflection.h",
"generated_message_bases.h",
@@ -754,6 +755,7 @@ cc_library(
"generated_message_reflection.cc",
"generated_message_tctable_full.cc",
"generated_message_tctable_gen.cc",
+ "internal_feature_helper.cc",
"map_field.cc",
"message.cc",
"reflection_mode.cc",
@@ -1704,6 +1706,37 @@ cc_test(
],
)
+cc_test(
+ name = "internal_feature_helper_test",
+ srcs = [
+ "internal_feature_helper_test.cc",
+ ],
+ copts = COPTS,
+ deps = [
+ ":cc_test_protos",
+ ":port",
+ ":protobuf",
+ ":protobuf_lite",
+ ":test_textproto",
+ ":test_util",
+ "//src/google/protobuf/compiler:importer",
+ "//src/google/protobuf/io",
+ "//src/google/protobuf/io:tokenizer",
+ "//src/google/protobuf/testing",
+ "//src/google/protobuf/testing:file",
+ "@abseil-cpp//absl/log:absl_check",
+ "@abseil-cpp//absl/log:absl_log",
+ "@abseil-cpp//absl/log:die_if_null",
+ "@abseil-cpp//absl/memory",
+ "@abseil-cpp//absl/status",
+ "@abseil-cpp//absl/status:statusor",
+ "@abseil-cpp//absl/strings",
+ "@abseil-cpp//absl/strings:str_format",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
+ ],
+)
+
cc_test(
name = "generated_message_reflection_unittest",
srcs = ["generated_message_reflection_unittest.cc"],
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index b0d9a5f1d2fe6..d5ffa04a12c74 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/any.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/any.pb.h"
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index cda85dd611510..4110bf7b2f45f 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/any.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fany_2eproto_2epb_2eh
#define google_2fprotobuf_2fany_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index c3f2957c95a45..38f45571d6f79 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/api.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/api.pb.h"
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 811678bf7cfc5..02a895e8234d8 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/api.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fapi_2eproto_2epb_2eh
#define google_2fprotobuf_2fapi_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
index 683a4276eb76e..552dc3dcc28f0 100644
--- a/src/google/protobuf/compiler/code_generator.h
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -25,6 +25,7 @@
#include "google/protobuf/compiler/code_generator_lite.h" // IWYU pragma: export
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/internal_feature_helper.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
@@ -142,6 +143,20 @@ class PROTOC_EXPORT CodeGenerator {
return ::google::protobuf::internal::InternalFeatureHelper::GetFeatures(desc);
}
+ // Returns the resolved FeatureSet for the language extension. It is
+ // guaranteed that the result is fully aware of the language feature set
+ // defaults, either the defaults set to the descriptor pool, or, if not set,
+ // the defaults embedded in the language FeatureSet extension.
+ template
+ static auto GetResolvedSourceFeatureExtension(
+ const DescriptorT& desc,
+ const google::protobuf::internal::ExtensionIdentifier<
+ FeatureSet, TypeTraitsT, field_type, is_packed>& extension) {
+ return ::google::protobuf::internal::InternalFeatureHelper::
+ GetResolvedFeatureExtension(desc, extension);
+ }
+
// Retrieves the unresolved source features for a given descriptor. These
// should be used to validate the original .proto file. These represent the
// original proto files from generated code, but should be stripped of
diff --git a/src/google/protobuf/compiler/code_generator_unittest.cc b/src/google/protobuf/compiler/code_generator_unittest.cc
index 6167498a17193..4e55f7b528968 100644
--- a/src/google/protobuf/compiler/code_generator_unittest.cc
+++ b/src/google/protobuf/compiler/code_generator_unittest.cc
@@ -67,6 +67,7 @@ class TestGenerator : public CodeGenerator {
}
// Expose the protected methods for testing.
+ using CodeGenerator::GetResolvedSourceFeatureExtension;
using CodeGenerator::GetResolvedSourceFeatures;
using CodeGenerator::GetUnresolvedSourceFeatures;
@@ -246,6 +247,143 @@ TEST_F(CodeGeneratorTest, GetResolvedSourceFeaturesInherited) {
EXPECT_EQ(ext.source_feature2(), pb::EnumFeature::VALUE3);
}
+TEST_F(CodeGeneratorTest, GetResolvedSourceFeatureExtension) {
+ TestGenerator generator;
+ generator.set_feature_extensions({GetExtensionReflection(pb::test)});
+ ASSERT_OK(pool_.SetFeatureSetDefaults(*generator.BuildFeatureSetDefaults()));
+
+ ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull());
+ ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull());
+ auto file = BuildFile(R"schema(
+ edition = "2023";
+ package proto2_unittest;
+
+ import "google/protobuf/unittest_features.proto";
+
+ option features.(pb.test).file_feature = VALUE6;
+ option features.(pb.test).source_feature = VALUE5;
+ )schema");
+ ASSERT_THAT(file, NotNull());
+ const pb::TestFeatures& ext1 =
+ TestGenerator::GetResolvedSourceFeatureExtension(*file, pb::test);
+ const pb::TestFeatures& ext2 =
+ TestGenerator::GetResolvedSourceFeatures(*file).GetExtension(pb::test);
+
+ // Since the pool provides the feature set defaults, there should be no
+ // difference between the two results.
+ EXPECT_EQ(ext1.enum_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.field_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext1.source_feature(), pb::EnumFeature::VALUE5);
+ EXPECT_EQ(ext2.enum_feature(), ext1.enum_feature());
+ EXPECT_EQ(ext2.field_feature(), ext1.field_feature());
+ EXPECT_EQ(ext2.file_feature(), ext1.file_feature());
+ EXPECT_EQ(ext2.source_feature(), ext1.source_feature());
+}
+
+TEST_F(CodeGeneratorTest, GetResolvedSourceFeatureExtensionEditedDefaults) {
+ FeatureSetDefaults defaults = ParseTextOrDie(R"pb(
+ minimum_edition: EDITION_PROTO2
+ maximum_edition: EDITION_2024
+ defaults {
+ edition: EDITION_LEGACY
+ overridable_features {}
+ fixed_features {
+ field_presence: EXPLICIT
+ enum_type: CLOSED
+ repeated_field_encoding: EXPANDED
+ utf8_validation: NONE
+ message_encoding: LENGTH_PREFIXED
+ json_format: LEGACY_BEST_EFFORT
+ enforce_naming_style: STYLE_LEGACY
+ default_symbol_visibility: EXPORT_ALL
+ }
+ }
+ defaults {
+ edition: EDITION_2023
+ overridable_features {
+ field_presence: EXPLICIT
+ enum_type: OPEN
+ repeated_field_encoding: PACKED
+ utf8_validation: VERIFY
+ message_encoding: LENGTH_PREFIXED
+ json_format: ALLOW
+ [pb.test] {
+ file_feature: VALUE3
+ field_feature: VALUE15
+ enum_feature: VALUE14
+ source_feature: VALUE1
+ }
+ }
+ fixed_features {
+ enforce_naming_style: STYLE_LEGACY
+ default_symbol_visibility: EXPORT_ALL
+ }
+ }
+ )pb");
+ ASSERT_OK(pool_.SetFeatureSetDefaults(defaults));
+
+ ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull());
+ ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull());
+ auto file = BuildFile(R"schema(
+ edition = "2023";
+ package proto2_unittest;
+
+ import "google/protobuf/unittest_features.proto";
+
+ option features.(pb.test).file_feature = VALUE6;
+ option features.(pb.test).source_feature = VALUE5;
+ )schema");
+ ASSERT_THAT(file, NotNull());
+ const pb::TestFeatures& ext =
+ TestGenerator::GetResolvedSourceFeatureExtension(*file, pb::test);
+
+ // Since the pool provides the modified feature set defaults, the result
+ // should be the one reflecting the pool's defaults.
+ EXPECT_EQ(ext.enum_feature(), pb::EnumFeature::VALUE14);
+ EXPECT_EQ(ext.field_feature(), pb::EnumFeature::VALUE15);
+ EXPECT_EQ(ext.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext.source_feature(), pb::EnumFeature::VALUE5);
+}
+
+TEST_F(CodeGeneratorTest,
+ GetResolvedSourceFeatureExtensionDefaultsFromFeatureSetExtension) {
+ // Make sure feature set defaults are empty in the pool.
+ TestGenerator generator;
+ generator.set_feature_extensions({});
+ ASSERT_OK(pool_.SetFeatureSetDefaults(*generator.BuildFeatureSetDefaults()));
+
+ ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull());
+ ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull());
+ auto file = BuildFile(R"schema(
+ edition = "2023";
+ package proto2_unittest;
+
+ import "google/protobuf/unittest_features.proto";
+
+ option features.(pb.test).file_feature = VALUE6;
+ option features.(pb.test).source_feature = VALUE5;
+ )schema");
+ ASSERT_THAT(file, NotNull());
+
+ const pb::TestFeatures& ext1 =
+ TestGenerator::GetResolvedSourceFeatureExtension(*file, pb::test);
+ const pb::TestFeatures& ext2 =
+ TestGenerator::GetResolvedSourceFeatures(*file).GetExtension(pb::test);
+
+ // No defaults were added to the pool, but they should be still present in the
+ // result. On the other hand, features that are explicitly set should be also
+ // present.
+ EXPECT_EQ(ext1.enum_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.field_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext1.source_feature(), pb::EnumFeature::VALUE5);
+ EXPECT_EQ(ext2.enum_feature(), pb::EnumFeature::TEST_ENUM_FEATURE_UNKNOWN);
+ EXPECT_EQ(ext2.field_feature(), pb::EnumFeature::TEST_ENUM_FEATURE_UNKNOWN);
+ EXPECT_EQ(ext2.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext2.source_feature(), pb::EnumFeature::VALUE5);
+}
+
// TODO: Use the gtest versions once that's available in OSS.
MATCHER_P(HasError, msg_matcher, "") {
return arg.status().code() == absl::StatusCode::kFailedPrecondition &&
diff --git a/src/google/protobuf/compiler/cpp/BUILD.bazel b/src/google/protobuf/compiler/cpp/BUILD.bazel
index 81b2502de3c21..37a47de81ae2c 100644
--- a/src/google/protobuf/compiler/cpp/BUILD.bazel
+++ b/src/google/protobuf/compiler/cpp/BUILD.bazel
@@ -147,6 +147,7 @@ cc_library(
"@abseil-cpp//absl/log:die_if_null",
"@abseil-cpp//absl/memory",
"@abseil-cpp//absl/status",
+ "@abseil-cpp//absl/status:statusor",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/strings:str_format",
"@abseil-cpp//absl/synchronization",
diff --git a/src/google/protobuf/compiler/cpp/extension.cc b/src/google/protobuf/compiler/cpp/extension.cc
index 3dd9410b8fabd..178548e44abd0 100644
--- a/src/google/protobuf/compiler/cpp/extension.cc
+++ b/src/google/protobuf/compiler/cpp/extension.cc
@@ -15,12 +15,17 @@
#include
#include "absl/log/absl_check.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
+#include "absl/strings/string_view.h"
+#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/compiler/cpp/options.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/feature_resolver.h"
#include "google/protobuf/io/printer.h"
namespace google {
@@ -96,30 +101,67 @@ bool ExtensionGenerator::IsScoped() const {
return descriptor_->extension_scope() != nullptr;
}
+namespace {
+bool ShouldGenerateFeatureSetDefaultData(absl::string_view extension) {
+ return extension == "pb.java" || extension == "pb.test";
+}
+} // namespace
+
void ExtensionGenerator::GenerateDeclaration(io::Printer* p) const {
auto var = p->WithVars(variables_);
auto annotate = p->WithAnnotations({{"name", descriptor_}});
- p->Emit({{"constant_qualifier",
- // If this is a class member, it needs to be declared
- // `static constexpr`.
- // Otherwise, it will be
- // `inline constexpr`.
- IsScoped() ? "static" : ""},
- {"id_qualifier",
- // If this is a class member, it needs to be declared "static".
- // Otherwise, it needs to be "extern". In the latter case, it
- // also needs the DLL export/import specifier.
- IsScoped() ? "static"
- : options_.dllexport_decl.empty()
- ? "extern"
- : absl::StrCat(options_.dllexport_decl, " extern")}},
- R"cc(
- inline $constant_qualifier $constexpr int $constant_name$ =
- $number$;
- $id_qualifier$ $pbi$::ExtensionIdentifier<
- $extendee$, $pbi$::$type_traits$, $field_type$, $packed$>
- $name$;
- )cc");
+ p->Emit(
+ {{"constant_qualifier",
+ // If this is a class member, it needs to be declared
+ // `static constexpr`.
+ // Otherwise, it will be
+ // `inline constexpr`.
+ IsScoped() ? "static" : ""},
+ {"id_qualifier",
+ // If this is a class member, it needs to be declared "static".
+ // Otherwise, it needs to be "extern". In the latter case, it
+ // also needs the DLL export/import specifier.
+ IsScoped() ? "static"
+ : options_.dllexport_decl.empty()
+ ? "extern"
+ : absl::StrCat(options_.dllexport_decl, " extern")},
+ {"feature_set_defaults",
+ [&] {
+ if (!ShouldGenerateFeatureSetDefaultData(descriptor_->full_name())) {
+ return;
+ }
+ if (descriptor_->message_type() == nullptr) return;
+ absl::string_view extendee =
+ descriptor_->containing_type()->full_name();
+ if (extendee != "google.protobuf.FeatureSet") return;
+
+ std::vector extensions = {descriptor_};
+ absl::StatusOr defaults =
+ FeatureResolver::CompileDefaults(
+ descriptor_->containing_type(), extensions,
+ ProtocMinimumEdition(), ProtocMaximumEdition());
+ ABSL_CHECK_OK(defaults);
+ p->Emit(
+ {{"defaults", absl::Base64Escape(defaults->SerializeAsString())},
+ {"extension_type", ClassName(descriptor_->message_type(), true)},
+ {"function_name", "GetFeatureSetDefaultsData"}},
+ R"cc(
+ namespace internal {
+ template <>
+ inline ::absl::string_view $function_name$<$extension_type$>() {
+ static constexpr char kDefaults[] = "$defaults$";
+ return kDefaults;
+ }
+ } // namespace internal
+ )cc");
+ }}},
+ R"cc(
+ inline $constant_qualifier $constexpr int $constant_name$ = $number$;
+ $id_qualifier$ $pbi$::ExtensionIdentifier<
+ $extendee$, $pbi$::$type_traits$, $field_type$, $packed$>
+ $name$;
+ $feature_set_defaults$;
+ )cc");
}
void ExtensionGenerator::GenerateDefinition(io::Printer* p) {
diff --git a/src/google/protobuf/compiler/java/BUILD.bazel b/src/google/protobuf/compiler/java/BUILD.bazel
index 458a9ef37b0a4..58c4ba48da543 100644
--- a/src/google/protobuf/compiler/java/BUILD.bazel
+++ b/src/google/protobuf/compiler/java/BUILD.bazel
@@ -85,6 +85,7 @@ cc_library(
"generator.h",
"internal_helpers.h",
],
+ copts = COPTS,
strip_include_prefix = "/src",
visibility = [
"//src/google/protobuf/compiler/java:__subpackages__",
diff --git a/src/google/protobuf/compiler/java/generator.h b/src/google/protobuf/compiler/java/generator.h
index 4abf7ce32228b..17202d47e916d 100644
--- a/src/google/protobuf/compiler/java/generator.h
+++ b/src/google/protobuf/compiler/java/generator.h
@@ -60,6 +60,7 @@ class PROTOC_EXPORT JavaGenerator : public CodeGenerator {
}
using CodeGenerator::GetEdition;
+ using CodeGenerator::GetResolvedSourceFeatureExtension;
using CodeGenerator::GetResolvedSourceFeatures;
using CodeGenerator::GetUnresolvedSourceFeatures;
diff --git a/src/google/protobuf/compiler/java/helpers.cc b/src/google/protobuf/compiler/java/helpers.cc
index 19b191a670ce2..448c2141344e0 100644
--- a/src/google/protobuf/compiler/java/helpers.cc
+++ b/src/google/protobuf/compiler/java/helpers.cc
@@ -929,15 +929,12 @@ namespace {
// generated class should be nested in the generated proto file Java class.
template
inline bool NestInFileClass(const Descriptor& descriptor) {
- auto nest_in_file_class = JavaGenerator::GetResolvedSourceFeatures(descriptor)
- .GetExtension(pb::java)
- .nest_in_file_class();
+ auto nest_in_file_class =
+ JavaGenerator::GetResolvedSourceFeatureExtension(descriptor, pb::java)
+ .nest_in_file_class();
ABSL_CHECK(
nest_in_file_class !=
- pb::JavaFeatures::NestInFileClassFeature::NEST_IN_FILE_CLASS_UNKNOWN)
- << "Unknown value for nest_in_file_class feature. Try populating the "
- "Java feature set defaults in your generator plugin or custom "
- "descriptor pool.";
+ pb::JavaFeatures::NestInFileClassFeature::NEST_IN_FILE_CLASS_UNKNOWN);
if (nest_in_file_class == pb::JavaFeatures::NestInFileClassFeature::LEGACY) {
return !descriptor.file()->options().java_multiple_files();
diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc
index 9a72149b16080..e8155844e6cd1 100644
--- a/src/google/protobuf/compiler/java/java_features.pb.cc
+++ b/src/google/protobuf/compiler/java/java_features.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/compiler/java/java_features.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/compiler/java/java_features.pb.h"
diff --git a/src/google/protobuf/compiler/java/java_features.pb.h b/src/google/protobuf/compiler/java/java_features.pb.h
index 72dbafd45e196..467af1ca62080 100644
--- a/src/google/protobuf/compiler/java/java_features.pb.h
+++ b/src/google/protobuf/compiler/java/java_features.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/compiler/java/java_features.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh
#define google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
@@ -591,11 +591,17 @@ PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull JavaFeatu
-inline constexpr int kJavaFieldNumber =
- 1001;
+inline constexpr int kJavaFieldNumber = 1001;
PROTOC_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier<
::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, 11, false>
java;
+namespace internal {
+template <>
+inline ::absl::string_view GetFeatureSetDefaultsData<::pb::JavaFeatures>() {
+ static constexpr char kDefaults[] = "CicYhAciA8o+ACodCAEQAhgCIAMoATACOAJAAco+CggBEAEYACABKAMKJxjnByIDyj4AKh0IAhABGAEgAigBMAE4AkAByj4KCAAQARgAIAEoAwonGOgHIhMIARABGAEgAigBMAHKPgQIABABKg04AkAByj4GGAAgASgDIOYHKOgH";
+ return kDefaults;
+}
+} // namespace internal
// ===================================================================
diff --git a/src/google/protobuf/compiler/java/name_resolver.cc b/src/google/protobuf/compiler/java/name_resolver.cc
index 6002a21645942..418f26f87deaf 100644
--- a/src/google/protobuf/compiler/java/name_resolver.cc
+++ b/src/google/protobuf/compiler/java/name_resolver.cc
@@ -38,11 +38,7 @@ namespace {
const char* kOuterClassNameSuffix = "OuterClass";
inline bool UseOldFileClassNameDefault(const FileDescriptor* file) {
- // TODO b/373884685 - Clean up this check once when we have a way to query
- // Java features in the C++ runtime.
- if (JavaGenerator::GetEdition(*file) < EDITION_2024) return true;
- return JavaGenerator::GetResolvedSourceFeatures(*file)
- .GetExtension(pb::java)
+ return JavaGenerator::GetResolvedSourceFeatureExtension(*file, pb::java)
.use_old_outer_classname_default();
}
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 116f46c9fc55c..dcb42cbdeb890 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/compiler/plugin.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/compiler/plugin.pb.h"
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index 65326a7f3fba2..2b623100110ee 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/compiler/plugin.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh
#define google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc
index d687259cf9c73..31e1fb8545485 100644
--- a/src/google/protobuf/compiler/python/pyi_generator.cc
+++ b/src/google/protobuf/compiler/python/pyi_generator.cc
@@ -73,6 +73,7 @@ struct ImportModules {
bool has_union = false; // typing.Union
bool has_callable = false; // typing.Callable
bool has_well_known_type = false;
+ bool has_datetime = false;
};
// Checks whether a descriptor name matches a well-known type.
@@ -112,8 +113,15 @@ void CheckImportModules(const Descriptor* descriptor,
if (field->is_map()) {
import_modules->has_mapping = true;
const FieldDescriptor* value_des = field->message_type()->field(1);
- if (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
- value_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ if (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ import_modules->has_union = true;
+ const absl::string_view name = value_des->message_type()->full_name();
+ if (name == "google.protobuf.Duration" ||
+ name == "google.protobuf.Timestamp") {
+ import_modules->has_datetime = true;
+ }
+ }
+ if (value_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
import_modules->has_union = true;
}
} else {
@@ -123,6 +131,11 @@ void CheckImportModules(const Descriptor* descriptor,
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
import_modules->has_union = true;
import_modules->has_mapping = true;
+ const absl::string_view name = field->message_type()->full_name();
+ if (name == "google.protobuf.Duration" ||
+ name == "google.protobuf.Timestamp") {
+ import_modules->has_datetime = true;
+ }
}
if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
import_modules->has_union = true;
@@ -170,21 +183,6 @@ void PyiGenerator::PrintImportForDescriptor(
}
void PyiGenerator::PrintImports() const {
- // Prints imported dependent _pb2 files.
- absl::flat_hash_set seen_aliases;
- bool has_importlib = false;
- for (int i = 0; i < file_->dependency_count(); ++i) {
- const FileDescriptor* dep = file_->dependency(i);
- if (strip_nonfunctional_codegen_ && IsKnownFeatureProto(dep->name())) {
- continue;
- }
- PrintImportForDescriptor(*dep, &seen_aliases, &has_importlib);
- for (int j = 0; j < dep->public_dependency_count(); ++j) {
- PrintImportForDescriptor(*dep->public_dependency(j), &seen_aliases,
- &has_importlib);
- }
- }
-
// Checks what modules should be imported.
ImportModules import_modules;
if (file_->message_type_count() > 0) {
@@ -201,6 +199,24 @@ void PyiGenerator::PrintImports() const {
for (int i = 0; i < file_->message_type_count(); i++) {
CheckImportModules(file_->message_type(i), &import_modules);
}
+ if (import_modules.has_datetime) {
+ printer_->Print("import datetime\n\n");
+ }
+
+ // Prints imported dependent _pb2 files.
+ absl::flat_hash_set seen_aliases;
+ bool has_importlib = false;
+ for (int i = 0; i < file_->dependency_count(); ++i) {
+ const FileDescriptor* dep = file_->dependency(i);
+ if (strip_nonfunctional_codegen_ && IsKnownFeatureProto(dep->name())) {
+ continue;
+ }
+ PrintImportForDescriptor(*dep, &seen_aliases, &has_importlib);
+ for (int j = 0; j < dep->public_dependency_count(); ++j) {
+ PrintImportForDescriptor(*dep->public_dependency(j), &seen_aliases,
+ &has_importlib);
+ }
+ }
// Prints modules (e.g. _containers, _messages, typing) that are
// required in the proto file.
diff --git a/src/google/protobuf/compiler/versions.h b/src/google/protobuf/compiler/versions.h
index 17f52e3a6885d..8d821c3ba34a7 100644
--- a/src/google/protobuf/compiler/versions.h
+++ b/src/google/protobuf/compiler/versions.h
@@ -53,10 +53,10 @@
//
// Please avoid changing them manually, as they should be updated automatically
// by Protobuf release process.
-#define PROTOBUF_CPP_VERSION_STRING "6.31.0"
-#define PROTOBUF_JAVA_VERSION_STRING "4.31.0"
-#define PROTOBUF_PYTHON_VERSION_STRING "6.31.0"
-#define PROTOBUF_RUST_VERSION_STRING "4.31.0"
+#define PROTOBUF_CPP_VERSION_STRING "6.31.1"
+#define PROTOBUF_JAVA_VERSION_STRING "4.31.1"
+#define PROTOBUF_PYTHON_VERSION_STRING "6.31.1"
+#define PROTOBUF_RUST_VERSION_STRING "4.31.1"
namespace google {
diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc
index b3a24523c06fe..0b85061c361bc 100644
--- a/src/google/protobuf/cpp_features.pb.cc
+++ b/src/google/protobuf/cpp_features.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/cpp_features.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/cpp_features.pb.h"
diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h
index ecc5050b11553..6920a52aaa0b9 100644
--- a/src/google/protobuf/cpp_features.pb.h
+++ b/src/google/protobuf/cpp_features.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/cpp_features.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh
#define google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
@@ -354,8 +354,7 @@ PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull CppFeat
-inline constexpr int kCppFieldNumber =
- 1000;
+inline constexpr int kCppFieldNumber = 1000;
PROTOBUF_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier<
::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, false>
cpp;
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 7456d3c3d6653..f97d2065a3247 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -78,6 +78,7 @@
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/feature_resolver.h"
#include "google/protobuf/generated_message_util.h"
+#include "google/protobuf/internal_feature_helper.h"
#include "google/protobuf/io/strtod.h"
#include "google/protobuf/io/tokenizer.h"
#include "google/protobuf/message.h"
@@ -10711,9 +10712,6 @@ namespace internal {
absl::string_view ShortEditionName(Edition edition) {
return absl::StripPrefix(Edition_Name(edition), "EDITION_");
}
-Edition InternalFeatureHelper::GetEdition(const FileDescriptor& desc) {
- return desc.edition();
-}
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index f0d1ba647f492..af6222a5fb6c7 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -148,6 +148,10 @@ namespace io {
class Printer;
} // namespace io
+namespace internal {
+class InternalFeatureHelper;
+} // namespace internal
+
// NB, all indices are zero-based.
struct SourceLocation {
int start_line;
@@ -320,41 +324,6 @@ class PROTOBUF_EXPORT SymbolBase {
template
class PROTOBUF_EXPORT SymbolBaseN : public SymbolBase {};
-// This class is for internal use only and provides access to the resolved
-// runtime FeatureSets of any descriptor. These features are not designed
-// to be stable, and depending directly on them (vs the public descriptor APIs)
-// is not safe.
-class PROTOBUF_EXPORT InternalFeatureHelper {
- public:
- template
- static const FeatureSet& GetFeatures(const DescriptorT& desc) {
- return desc.features();
- }
-
- private:
- friend class ::google::protobuf::compiler::CodeGenerator;
- friend class ::google::protobuf::compiler::CommandLineInterface;
-
- // Provides a restricted view exclusively to code generators to query their
- // own unresolved features. Unresolved features are virtually meaningless to
- // everyone else. Code generators will need them to validate their own
- // features, and runtimes may need them internally to be able to properly
- // represent the original proto files from generated code.
- template
- static typename TypeTraitsT::ConstType GetUnresolvedFeatures(
- const DescriptorT& descriptor,
- const google::protobuf::internal::ExtensionIdentifier<
- FeatureSet, TypeTraitsT, field_type, is_packed>& extension) {
- return descriptor.proto_features_->GetExtension(extension);
- }
-
- // Provides a restricted view exclusively to code generators to query the
- // edition of files being processed. While most people should never write
- // edition-dependent code, generators frequently will need to.
- static Edition GetEdition(const FileDescriptor& desc);
-};
-
PROTOBUF_EXPORT absl::string_view ShortEditionName(Edition edition);
bool IsEnumFullySequential(const EnumDescriptor* enum_desc);
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index d3dc31823fc00..637fb2d9b3a2e 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/descriptor.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/descriptor.pb.h"
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 760c8035ea032..eca29b66f9db2 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/descriptor.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh
#define google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 626b6f999dae5..1b744ca46e587 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -62,6 +62,7 @@
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/feature_resolver.h"
+#include "google/protobuf/internal_feature_helper.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/tokenizer.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index 7aff062120411..0082e2454d9fe 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/duration.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/duration.pb.h"
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 3f93f863ba983..28e6cb0a3c088 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/duration.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fduration_2eproto_2epb_2eh
#define google_2fprotobuf_2fduration_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index ace50306ab6a4..92ba7143e5b3b 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/empty.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/empty.pb.h"
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index 8427b07b670c2..454e9b7b36b12 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/empty.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fempty_2eproto_2epb_2eh
#define google_2fprotobuf_2fempty_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index fafd21e9fe3c1..37c2da3deb185 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -33,6 +33,7 @@
#include "absl/base/prefetch.h"
#include "absl/container/btree_map.h"
#include "absl/log/absl_check.h"
+#include "absl/strings/string_view.h"
#include "google/protobuf/generated_enum_util.h"
#include "google/protobuf/internal_visibility.h"
#include "google/protobuf/port.h"
@@ -76,6 +77,13 @@ void InitializeLazyExtensionSet();
} // namespace google
namespace pb {
class CppFeatures;
+namespace internal {
+// Forward-declares the function for FeatureSet extensions to make it visible
+// to the internal feature helper. It should hold and return serialized
+// FeatureSetDefaults data.
+template
+inline ::absl::string_view GetFeatureSetDefaultsData();
+} // namespace internal
} // namespace pb
namespace google {
diff --git a/src/google/protobuf/feature_resolver.cc b/src/google/protobuf/feature_resolver.cc
index 731ccb9822840..f5b8abae08d4f 100644
--- a/src/google/protobuf/feature_resolver.cc
+++ b/src/google/protobuf/feature_resolver.cc
@@ -526,21 +526,10 @@ absl::StatusOr FeatureResolver::Create(
prev_edition = edition_default.edition();
}
- // Select the matching edition defaults.
- auto comparator = [](const auto& a, const auto& b) {
- return a.edition() < b.edition();
- };
- FeatureSetDefaults::FeatureSetEditionDefault search;
- search.set_edition(edition);
- auto first_nonmatch =
- absl::c_upper_bound(compiled_defaults.defaults(), search, comparator);
- if (first_nonmatch == compiled_defaults.defaults().begin()) {
- return Error("No valid default found for edition ", edition);
- }
-
- FeatureSet features = std::prev(first_nonmatch)->fixed_features();
- features.MergeFrom(std::prev(first_nonmatch)->overridable_features());
- return FeatureResolver(std::move(features));
+ auto features =
+ internal::GetEditionFeatureSetDefaults(edition, compiled_defaults);
+ RETURN_IF_ERROR(features.status());
+ return FeatureResolver(std::move(features.value()));
}
absl::StatusOr FeatureResolver::MergeFeatures(
@@ -581,6 +570,25 @@ FeatureResolver::ValidationResults FeatureResolver::ValidateFeatureLifetimes(
return results;
}
+namespace internal {
+absl::StatusOr GetEditionFeatureSetDefaults(
+ Edition edition, const FeatureSetDefaults& defaults) {
+ // Select the matching edition defaults.
+ auto comparator = [](const auto& a, const auto& b) {
+ return a.edition() < b.edition();
+ };
+ FeatureSetDefaults::FeatureSetEditionDefault search;
+ search.set_edition(edition);
+ auto first_nonmatch =
+ absl::c_upper_bound(defaults.defaults(), search, comparator);
+ if (first_nonmatch == defaults.defaults().begin()) {
+ return Error("No valid default found for edition ", edition);
+ }
+ FeatureSet features = std::prev(first_nonmatch)->fixed_features();
+ features.MergeFrom(std::prev(first_nonmatch)->overridable_features());
+ return features;
+}
+} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/feature_resolver.h b/src/google/protobuf/feature_resolver.h
index 543cf9850037d..d66c156e2f66d 100644
--- a/src/google/protobuf/feature_resolver.h
+++ b/src/google/protobuf/feature_resolver.h
@@ -80,9 +80,15 @@ class PROTOBUF_EXPORT FeatureResolver {
FeatureSet defaults_;
};
+namespace internal {
+// Gets the default feature set for a given edition.
+absl::StatusOr PROTOBUF_EXPORT GetEditionFeatureSetDefaults(
+ Edition edition, const FeatureSetDefaults& defaults);
+} // namespace internal
} // namespace protobuf
} // namespace google
+#include "google/protobuf/port_undef.inc"
+
#endif // GOOGLE_PROTOBUF_FEATURE_RESOLVER_H__
-#include "google/protobuf/port_undef.inc"
diff --git a/src/google/protobuf/feature_resolver_test.cc b/src/google/protobuf/feature_resolver_test.cc
index eb27662f8b6e7..341b69ae72825 100644
--- a/src/google/protobuf/feature_resolver_test.cc
+++ b/src/google/protobuf/feature_resolver_test.cc
@@ -562,6 +562,46 @@ TEST(FeatureResolverTest, MergeFeaturesDistantFuture) {
HasSubstr("maximum supported edition 99997_TEST_ONLY"))));
}
+TEST(FeatureResolverTest, GetEditionFeatureSetDefaults) {
+ absl::StatusOr defaults =
+ FeatureResolver::CompileDefaults(FeatureSet::descriptor(),
+ {GetExtension(pb::test)}, EDITION_LEGACY,
+ EDITION_99997_TEST_ONLY);
+
+ absl::StatusOr edition_2023_feature =
+ internal::GetEditionFeatureSetDefaults(EDITION_2023, *defaults);
+ absl::StatusOr edition_proto3_feature =
+ internal::GetEditionFeatureSetDefaults(EDITION_PROTO3, *defaults);
+ absl::StatusOr edition_proto2_feature =
+ internal::GetEditionFeatureSetDefaults(EDITION_LEGACY, *defaults);
+ absl::StatusOr edition_test_feature =
+ internal::GetEditionFeatureSetDefaults(EDITION_99998_TEST_ONLY,
+ *defaults);
+ EXPECT_OK(edition_2023_feature);
+ EXPECT_EQ(edition_2023_feature->GetExtension(pb::test).file_feature(),
+ pb::VALUE3);
+ EXPECT_OK(edition_proto3_feature);
+ EXPECT_EQ(edition_proto3_feature->GetExtension(pb::test).file_feature(),
+ pb::VALUE2);
+ EXPECT_OK(edition_proto2_feature);
+ EXPECT_EQ(edition_proto2_feature->GetExtension(pb::test).file_feature(),
+ pb::VALUE1);
+ EXPECT_OK(edition_test_feature);
+ EXPECT_EQ(edition_test_feature->GetExtension(pb::test).file_feature(),
+ pb::VALUE4);
+}
+
+TEST(FeatureResolverTest, GetEditionFeatureSetDefaultsNotFound) {
+ absl::StatusOr defaults =
+ FeatureResolver::CompileDefaults(FeatureSet::descriptor(),
+ {GetExtension(pb::test)}, EDITION_2023,
+ EDITION_2023);
+
+ absl::StatusOr edition_2023_feature =
+ internal::GetEditionFeatureSetDefaults(EDITION_1_TEST_ONLY, *defaults);
+ EXPECT_THAT(edition_2023_feature, HasError(HasSubstr("No valid default")));
+}
+
TEST(FeatureResolverLifetimesTest, Valid) {
FeatureSet features = ParseTextOrDie(R"pb(
[pb.test] { file_feature: VALUE1 }
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index 4da0421cdd8d3..944d06c1e1c24 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/field_mask.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/field_mask.pb.h"
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index 2e334c65679f6..902c31bd66ec3 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/src/google/protobuf/field_mask.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/field_mask.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh
#define google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/internal_feature_helper.cc b/src/google/protobuf/internal_feature_helper.cc
new file mode 100644
index 0000000000000..a0a1c99cbbf91
--- /dev/null
+++ b/src/google/protobuf/internal_feature_helper.cc
@@ -0,0 +1,28 @@
+#include "google/protobuf/internal_feature_helper.h"
+
+#include
+
+#include "absl/log/absl_check.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/extension_set.h"
+#include "google/protobuf/feature_resolver.h"
+
+namespace google {
+namespace protobuf {
+namespace internal {
+FeatureSet InternalFeatureHelper::ParseAndGetEditionResolvedFeatureSet(
+ absl::string_view data, Edition edition) {
+ FeatureSetDefaults defaults;
+ std::string unescaped_data;
+ absl::Base64Unescape(data, &unescaped_data);
+ ABSL_CHECK(defaults.ParseFromString(unescaped_data));
+ auto edition_feature_set = GetEditionFeatureSetDefaults(edition, defaults);
+ ABSL_CHECK_OK(edition_feature_set);
+ return *edition_feature_set;
+}
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/internal_feature_helper.h b/src/google/protobuf/internal_feature_helper.h
new file mode 100644
index 0000000000000..f183778424842
--- /dev/null
+++ b/src/google/protobuf/internal_feature_helper.h
@@ -0,0 +1,109 @@
+#ifndef GOOGLE_PROTOBUF_INTERNAL_FEATURE_HELPER_H__
+#define GOOGLE_PROTOBUF_INTERNAL_FEATURE_HELPER_H__
+
+#include
+
+#include "absl/strings/string_view.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/extension_set.h"
+
+// Must be included last.
+#include "google/protobuf/port_def.inc"
+
+namespace google {
+namespace protobuf {
+namespace internal {
+class InternalFeatureHelperTest;
+// This class is for internal use only and provides access to the resolved
+// runtime FeatureSets of any descriptor. These features are not designed
+// to be stable, and depending directly on them (vs the public descriptor APIs)
+// is not safe.
+class PROTOBUF_EXPORT InternalFeatureHelper {
+ public:
+ template
+ static const FeatureSet& GetFeatures(const DescriptorT& desc) {
+ return desc.features();
+ }
+
+ private:
+ friend class ::google::protobuf::compiler::CodeGenerator;
+ friend class ::google::protobuf::compiler::CommandLineInterface;
+ friend class ::google::protobuf::internal::InternalFeatureHelperTest;
+
+ static const DescriptorPool& GetDescriptorPool(const FileDescriptor& file) {
+ return *file.pool();
+ }
+
+ template
+ static const DescriptorPool& GetDescriptorPool(const DescriptorT& desc) {
+ return GetDescriptorPool(*desc.file());
+ }
+
+ // Provides a restricted view exclusively to code generators to query their
+ // own unresolved features. Unresolved features are virtually meaningless to
+ // everyone else. Code generators will need them to validate their own
+ // features, and runtimes may need them internally to be able to properly
+ // represent the original proto files from generated code.
+ template
+ static typename TypeTraitsT::ConstType GetUnresolvedFeatures(
+ const DescriptorT& descriptor,
+ const google::protobuf::internal::ExtensionIdentifier<
+ FeatureSet, TypeTraitsT, field_type, is_packed>& extension) {
+ return descriptor.proto_features_->GetExtension(extension);
+ }
+
+ // Provides a restricted view exclusively to code generators to query the
+ // edition of files being processed. While most people should never write
+ // edition-dependent code, generators frequently will need to.
+ static Edition GetEdition(const FileDescriptor& desc) {
+ return desc.edition();
+ }
+
+ template
+ static Edition GetEdition(const DescriptorT& desc) {
+ return GetEdition(*desc.file());
+ }
+
+ // Parses the serialized FeatureSetDefaults and returns the resolved
+ // FeatureSet for a given edition.
+ static FeatureSet ParseAndGetEditionResolvedFeatureSet(absl::string_view data,
+ Edition edition);
+
+ // Gets the resolved FeatureSet extension for a given descriptor.
+ //
+ // If the descriptor's pool has already provided the resolved feature default
+ // for the edition and the language FeatureSet extension, then the default
+ // will be returned directly. Otherwise, the function will parse the
+ // serialized FeatureSetDefaults data provided by the language FeatureSet
+ // extension, and merge it with the original FeatureSet extension so that the
+ // resolved feature set defaults will always be present.
+ template
+ static auto GetResolvedFeatureExtension(
+ const DescriptorT& descriptor,
+ const google::protobuf::internal::ExtensionIdentifier<
+ FeatureSet, MessageTypeTraits, field_type, is_packed>&
+ extension) {
+ auto lang_features = GetFeatures(descriptor).GetExtension(extension);
+ if (GetDescriptorPool(descriptor).ResolvesFeaturesFor(extension)) {
+ return lang_features;
+ }
+
+ auto lang_features_ret =
+ ParseAndGetEditionResolvedFeatureSet(
+ ::pb::internal::GetFeatureSetDefaultsData(),
+ GetEdition(descriptor))
+ .GetExtension(extension);
+ lang_features_ret.MergeFrom(lang_features);
+ return lang_features_ret;
+ }
+};
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#include "google/protobuf/port_undef.inc"
+
+#endif // GOOGLE_PROTOBUF_INTERNAL_FEATURE_HELPER_H__
diff --git a/src/google/protobuf/internal_feature_helper_test.cc b/src/google/protobuf/internal_feature_helper_test.cc
new file mode 100644
index 0000000000000..5394e61749240
--- /dev/null
+++ b/src/google/protobuf/internal_feature_helper_test.cc
@@ -0,0 +1,210 @@
+#include "google/protobuf/internal_feature_helper.h"
+
+#include
+
+#include "google/protobuf/descriptor.pb.h"
+#include
+#include
+#include "absl/log/absl_check.h"
+#include "absl/log/absl_log.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "google/protobuf/compiler/parser.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/extension_set.h"
+#include "google/protobuf/feature_resolver.h"
+#include "google/protobuf/io/tokenizer.h"
+#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
+#include "google/protobuf/test_textproto.h"
+#include "google/protobuf/unittest_features.pb.h"
+
+// Must be included last.
+#include "google/protobuf/port_def.inc"
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+#define ASSERT_OK(x) ASSERT_TRUE(x.ok()) << x.message();
+
+using ::testing::NotNull;
+
+class SimpleErrorCollector : public io::ErrorCollector {
+ public:
+ void RecordError(int line, int column, absl::string_view message) override {
+ ABSL_LOG(ERROR) << absl::StrFormat("%d:%d:%s", line, column, message);
+ }
+};
+} // namespace
+
+class InternalFeatureHelperTest : public ::testing::Test {
+ protected:
+ template
+ static auto GetResolvedSourceFeatureExtension(
+ const DescriptorT& desc,
+ const google::protobuf::internal::ExtensionIdentifier<
+ FeatureSet, TypeTraitsT, field_type, is_packed>& extension) {
+ return ::google::protobuf::internal::InternalFeatureHelper::
+ GetResolvedFeatureExtension(desc, extension);
+ }
+
+ const FileDescriptor* BuildFile(absl::string_view schema) {
+ io::ArrayInputStream input_stream(schema.data(),
+ static_cast(schema.size()));
+ SimpleErrorCollector error_collector;
+ io::Tokenizer tokenizer(&input_stream, &error_collector);
+ compiler::Parser parser;
+ parser.RecordErrorsTo(&error_collector);
+ FileDescriptorProto proto;
+ ABSL_CHECK(parser.Parse(&tokenizer, &proto)) << schema;
+ proto.set_name("test.proto");
+ return pool_.BuildFile(proto);
+ }
+
+ const FileDescriptor* BuildFile(const FileDescriptor* file) {
+ FileDescriptorProto proto;
+ file->CopyTo(&proto);
+ return pool_.BuildFile(proto);
+ }
+ FeatureSetDefaults GetFeatureSetDefaults() {
+ auto defaults = FeatureResolver::CompileDefaults(
+ FeatureSet::descriptor(), {GetExtensionReflection(pb::test)},
+ EDITION_PROTO2, EDITION_2024);
+ ABSL_CHECK_OK(defaults);
+ return *defaults;
+ }
+
+ DescriptorPool pool_;
+};
+
+namespace {
+TEST_F(InternalFeatureHelperTest, GetResolvedSourceFeatureExtension) {
+ ASSERT_OK(pool_.SetFeatureSetDefaults(GetFeatureSetDefaults()));
+
+ ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull());
+ ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull());
+ auto file = BuildFile(R"schema(
+ edition = "2023";
+ package proto2_unittest;
+
+ import "google/protobuf/unittest_features.proto";
+
+ option features.(pb.test).file_feature = VALUE6;
+ option features.(pb.test).source_feature = VALUE5;
+ )schema");
+ ASSERT_THAT(file, NotNull());
+ const pb::TestFeatures& ext1 =
+ GetResolvedSourceFeatureExtension(*file, pb::test);
+ const pb::TestFeatures& ext2 =
+ InternalFeatureHelper::GetFeatures(*file).GetExtension(pb::test);
+ EXPECT_EQ(ext1.enum_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.field_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext1.source_feature(), pb::EnumFeature::VALUE5);
+ EXPECT_EQ(ext2.enum_feature(), ext1.enum_feature());
+ EXPECT_EQ(ext2.field_feature(), ext1.field_feature());
+ EXPECT_EQ(ext2.file_feature(), ext1.file_feature());
+ EXPECT_EQ(ext2.source_feature(), ext1.source_feature());
+}
+
+TEST_F(InternalFeatureHelperTest,
+ GetResolvedSourceFeatureExtensionEditedDefaults) {
+ FeatureSetDefaults defaults = ParseTextOrDie(R"pb(
+ minimum_edition: EDITION_PROTO2
+ maximum_edition: EDITION_2024
+ defaults {
+ edition: EDITION_LEGACY
+ overridable_features {}
+ fixed_features {
+ field_presence: EXPLICIT
+ enum_type: CLOSED
+ repeated_field_encoding: EXPANDED
+ utf8_validation: NONE
+ message_encoding: LENGTH_PREFIXED
+ json_format: LEGACY_BEST_EFFORT
+ enforce_naming_style: STYLE_LEGACY
+ default_symbol_visibility: EXPORT_ALL
+ }
+ }
+ defaults {
+ edition: EDITION_2023
+ overridable_features {
+ field_presence: EXPLICIT
+ enum_type: OPEN
+ repeated_field_encoding: PACKED
+ utf8_validation: VERIFY
+ message_encoding: LENGTH_PREFIXED
+ json_format: ALLOW
+ [pb.test] {
+ file_feature: VALUE3
+ field_feature: VALUE15
+ enum_feature: VALUE14
+ source_feature: VALUE1
+ }
+ }
+ fixed_features {
+ enforce_naming_style: STYLE_LEGACY
+ default_symbol_visibility: EXPORT_ALL
+ }
+ }
+ )pb");
+ ASSERT_OK(pool_.SetFeatureSetDefaults(defaults));
+
+ ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull());
+ ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull());
+ auto file = BuildFile(R"schema(
+ edition = "2023";
+ package proto2_unittest;
+
+ import "google/protobuf/unittest_features.proto";
+
+ option features.(pb.test).file_feature = VALUE6;
+ option features.(pb.test).source_feature = VALUE5;
+ )schema");
+ ASSERT_THAT(file, NotNull());
+ const pb::TestFeatures& ext =
+ GetResolvedSourceFeatureExtension(*file, pb::test);
+
+ EXPECT_EQ(ext.enum_feature(), pb::EnumFeature::VALUE14);
+ EXPECT_EQ(ext.field_feature(), pb::EnumFeature::VALUE15);
+ EXPECT_EQ(ext.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext.source_feature(), pb::EnumFeature::VALUE5);
+}
+
+TEST_F(InternalFeatureHelperTest,
+ GetResolvedSourceFeatureExtensionDefaultsFromFeatureSetExtension) {
+ ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull());
+ ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull());
+ auto file = BuildFile(R"schema(
+ edition = "2023";
+ package proto2_unittest;
+
+ import "google/protobuf/unittest_features.proto";
+
+ option features.(pb.test).file_feature = VALUE6;
+ option features.(pb.test).source_feature = VALUE5;
+ )schema");
+ ASSERT_THAT(file, NotNull());
+
+ const pb::TestFeatures& ext1 =
+ GetResolvedSourceFeatureExtension(*file, pb::test);
+ const pb::TestFeatures& ext2 =
+ InternalFeatureHelper::GetFeatures(*file).GetExtension(pb::test);
+
+ EXPECT_EQ(ext1.enum_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.field_feature(), pb::EnumFeature::VALUE1);
+ EXPECT_EQ(ext1.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext1.source_feature(), pb::EnumFeature::VALUE5);
+ EXPECT_EQ(ext2.enum_feature(), pb::EnumFeature::TEST_ENUM_FEATURE_UNKNOWN);
+ EXPECT_EQ(ext2.field_feature(), pb::EnumFeature::TEST_ENUM_FEATURE_UNKNOWN);
+ EXPECT_EQ(ext2.file_feature(), pb::EnumFeature::VALUE6);
+ EXPECT_EQ(ext2.source_feature(), pb::EnumFeature::VALUE5);
+}
+
+#include "google/protobuf/port_undef.inc"
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/runtime_version.h b/src/google/protobuf/runtime_version.h
index 8f135c2b57cef..2fa48639c209f 100644
--- a/src/google/protobuf/runtime_version.h
+++ b/src/google/protobuf/runtime_version.h
@@ -18,7 +18,7 @@
#endif // PROTOBUF_OSS_VERSION_SUFFIX
// The OSS versions are not stripped to avoid merging conflicts.
-#define PROTOBUF_OSS_VERSION 6031000
+#define PROTOBUF_OSS_VERSION 6031001
#define PROTOBUF_OSS_VERSION_SUFFIX ""
#define PROTOBUF_VERSION PROTOBUF_OSS_VERSION
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 8e17fc63dfa22..c70e192f7e11c 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/source_context.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/source_context.pb.h"
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index 45155510a401b..779d31bf840f0 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/src/google/protobuf/source_context.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/source_context.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh
#define google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index 0b9f8e71ed5a5..be01b5af93d02 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/struct.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/struct.pb.h"
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 640c8d8ead631..cef8c7cfd674b 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/struct.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fstruct_2eproto_2epb_2eh
#define google_2fprotobuf_2fstruct_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index bcbc6c952efb6..54e08473ba1a0 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -44,7 +44,7 @@ namespace internal {
// The current version, represented as a single integer to make comparison
// easier: major * 10^6 + minor * 10^3 + micro
-#define GOOGLE_PROTOBUF_VERSION 6031000
+#define GOOGLE_PROTOBUF_VERSION 6031001
// A suffix string for alpha, beta or rc releases. Empty for stable releases.
#define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 0f7979cddefe1..ae7b7285d75df 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/timestamp.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/timestamp.pb.h"
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index 316e94c8ed40e..6ac7bd8f0bb7e 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/timestamp.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh
#define google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 263d54e2f2dfb..b2bf40149170a 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/type.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/type.pb.h"
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index 748adb7f07804..2b5f1a1c758ae 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/type.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2ftype_2eproto_2epb_2eh
#define google_2fprotobuf_2ftype_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index 55983e09df9f6..7a7a230214fef 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/wrappers.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#include "google/protobuf/wrappers.pb.h"
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index dfd6685e70e77..de948eeef2d9a 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/wrappers.proto
-// Protobuf C++ Version: 6.31.0
+// Protobuf C++ Version: 6.31.1
#ifndef google_2fprotobuf_2fwrappers_2eproto_2epb_2eh
#define google_2fprotobuf_2fwrappers_2eproto_2epb_2eh
@@ -12,7 +12,7 @@
#include
#include "google/protobuf/runtime_version.h"
-#if PROTOBUF_VERSION != 6031000
+#if PROTOBUF_VERSION != 6031001
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
diff --git a/version.json b/version.json
index c3425ad327559..5e5dd0f5e06db 100644
--- a/version.json
+++ b/version.json
@@ -1,18 +1,18 @@
{
"31.x": {
- "protoc_version": "31.0",
+ "protoc_version": "31.1",
"lts": false,
- "date": "2025-05-14",
+ "date": "2025-05-28",
"languages": {
- "cpp": "6.31.0",
- "csharp": "3.31.0",
- "java": "4.31.0",
- "javascript": "3.31.0",
- "objectivec": "4.31.0",
- "php": "4.31.0",
- "python": "6.31.0",
- "ruby": "4.31.0",
- "rust": "4.31.0"
+ "cpp": "6.31.1",
+ "csharp": "3.31.1",
+ "java": "4.31.1",
+ "javascript": "3.31.1",
+ "objectivec": "4.31.1",
+ "php": "4.31.1",
+ "python": "6.31.1",
+ "ruby": "4.31.1",
+ "rust": "4.31.1"
}
}
}
\ No newline at end of file