diff --git a/.bcr/metadata.template.json b/.bcr/metadata.template.json
index bfdb1084d5..b4d95e4830 100644
--- a/.bcr/metadata.template.json
+++ b/.bcr/metadata.template.json
@@ -4,110 +4,122 @@
{
"email": "protobuf-packages@google.com",
"github": "protobuf-team-bot",
+ "github_user_id": 105450428,
"name": "Protobuf Team"
},
{
"email": "sandyzhang@google.com",
"github": "zhangskz",
+ "github_user_id": 89936743,
"name": "Sandy Zhang"
},
{
"email": "mkruskal@google.com",
"github": "mkruskal-google",
+ "github_user_id": 62662355,
"name": "Mike Kruskal"
},
{
"email": "gberg@google.com",
"github": "googleberg",
+ "github_user_id": 107155935,
"name": "Jerry Berg"
},
{
"email": "deannagarcia@google.com",
"github": "deannagarcia",
+ "github_user_id": 69992229,
"name": "Deanna Garcia",
"do_not_notify": true
},
{
"email": "esrauch@google.com",
"github": "esrauchg",
+ "github_user_id": 140440793,
"name": "Em Rauch",
"do_not_notify": true
},
{
"email": "haberman@google.com",
"github": "haberman",
+ "github_user_id": 1270,
"name": "Josh Haberman",
"do_not_notify": true
},
- {
- "email": "hongshin@google.com",
- "github": "honglooker",
- "name": "Hong Shin",
- "do_not_notify": true
- },
{
"email": "jatl@google.com",
"github": "JasonLunn",
+ "github_user_id": 778854,
"name": "Jason Lunn",
"do_not_notify": true
},
{
"email": "jieluo@google.com",
"github": "anandolee",
+ "github_user_id": 11618033,
"name": "Jie Luo",
"do_not_notify": true
},
{
"email": "salo@google.com",
"github": "salo",
+ "github_user_id": 152465,
"name": "Eric Salo",
"do_not_notify": true
},
{
"email": "sangki@google.com",
"github": "jguamie",
+ "github_user_id": 35405521,
"name": "John Lee",
"do_not_notify": true
},
{
"email": "sbenza@google.com",
"github": "sbenzaquen",
+ "github_user_id": 14094653,
"name": "Samuel Benzaquen",
"do_not_notify": true
},
{
"email": "shaod@google.com",
"github": "shaod2",
+ "github_user_id": 67387070,
"name": "Dennis Shao",
"do_not_notify": true
},
{
"email": "tonyliaoss@google.com",
"github": "tonyliaoss",
+ "github_user_id": 1459994,
"name": "Tony Liao",
"do_not_notify": true
},
{
"email": "rgoldfinger@google.com",
"github": "rgoldfinger6",
+ "github_user_id": 94469227,
"name": "Rachel Goldfinger",
"do_not_notify": true
},
{
"email": "jamiepilgrim@google.com",
"github": "pilgrimmemoirs",
+ "github_user_id": 8316393,
"name": "Jamie Pilgrim",
"do_not_notify": true
},
{
"email": "karenwuz@google.com",
"github": "karenwuz",
+ "github_user_id": 242015323,
"name": "Karen Wu",
"do_not_notify": true
},
{
"email": "runze@google.com",
"github": "runzw",
+ "github_user_id": 78052475,
"name": "Runze Wang",
"do_not_notify": true
}
diff --git a/BUILD.bazel b/BUILD.bazel
index 6c13f7a319..8c8b2360cb 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -506,6 +506,12 @@ alias(
visibility = ["//visibility:public"],
)
+alias(
+ name = "json_enumvalue_options_proto_srcs",
+ actual = "//src/google/protobuf:json_enumvalue_options_proto_srcs",
+ visibility = ["//visibility:public"],
+)
+
alias(
name = "json_enumvalue_options_cc_proto",
actual = "//src/google/protobuf:json_enumvalue_options_cc_proto",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b7187778d..c23665e583 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,7 +91,7 @@ if (protobuf_BUILD_SHARED_LIBS)
endif ()
# Version metadata
-set(protobuf_VERSION_STRING "7.36.0")
+set(protobuf_VERSION_STRING "7.36.0-rc-2")
set(protobuf_DESCRIPTION "Protocol Buffers")
set(protobuf_CONTACT "protobuf@googlegroups.com")
diff --git a/MODULE.bazel b/MODULE.bazel
index 3c342e4063..7bd7930bc6 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -3,7 +3,7 @@
module(
name = "protobuf",
- version = "36.0-dev", # Automatically updated on release
+ version = "36.0-rc2", # Automatically updated on release
bazel_compatibility = [">=8.0.0"],
compatibility_level = 1,
repo_name = "com_google_protobuf",
@@ -212,7 +212,7 @@ crate.spec(
)
crate.spec(
package = "syn",
- version = ">=2",
+ version = "2",
)
crate.from_specs()
use_repo(crate, crate_index = "crates")
diff --git a/Protobuf.podspec b/Protobuf.podspec
index 1a06267bd0..1c122a122b 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 = '5.36.0'
+ s.version = '5.36.0-rc2'
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/cmake/install.cmake b/cmake/install.cmake
index 4d7d68fc6e..3e0e16558f 100644
--- a/cmake/install.cmake
+++ b/cmake/install.cmake
@@ -98,15 +98,8 @@ include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
set(protobuf_HEADERS
${libprotobuf_hdrs}
${libprotoc_public_hdrs}
- ${wkt_protos_files}
- ${cpp_file_options_proto_proto_srcs}
- ${json_enumvalue_options_proto_proto_srcs}
- ${cpp_features_proto_proto_srcs}
- ${descriptor_proto_proto_srcs}
${plugin_proto_proto_srcs}
- ${c_sharp_features_proto_proto_srcs}
- ${java_features_proto_proto_srcs}
- ${go_features_proto_proto_srcs}
+ ${release_all_options_protos_files}
)
if (protobuf_BUILD_LIBUPB)
list(APPEND protobuf_HEADERS ${libupb_hdrs})
@@ -115,6 +108,8 @@ if (protobuf_BUILD_LIBUPB)
FILES
${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/descriptor.upb.h
${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/descriptor.upb_minitable.h
+ ${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb.h
+ ${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/google/protobuf
COMPONENT protobuf-headers
)
diff --git a/cmake/installed_include_golden.txt b/cmake/installed_include_golden.txt
index a1a85b2076..a8646f6e36 100644
--- a/cmake/installed_include_golden.txt
+++ b/cmake/installed_include_golden.txt
@@ -45,6 +45,7 @@ google/protobuf/cpp_features.pb.h
google/protobuf/cpp_features.proto
google/protobuf/cpp_file_options.pb.h
google/protobuf/cpp_file_options.proto
+google/protobuf/cpp_options.proto
google/protobuf/descriptor.h
google/protobuf/descriptor.pb.h
google/protobuf/descriptor.proto
@@ -95,6 +96,9 @@ google/protobuf/java_features.proto
google/protobuf/json/json.h
google/protobuf/json_enumvalue_options.pb.h
google/protobuf/json_enumvalue_options.proto
+google/protobuf/json_enumvalue_options.upb.h
+google/protobuf/json_enumvalue_options.upb_minitable.h
+google/protobuf/json_options.proto
google/protobuf/map.h
google/protobuf/map_entry.h
google/protobuf/map_field.h
@@ -221,6 +225,7 @@ upb/reflection/enum_value_def.h
upb/reflection/extension_range.h
upb/reflection/field_def.h
upb/reflection/file_def.h
+upb/reflection/json_enumvalue_options_bootstrap.h
upb/reflection/message.h
upb/reflection/message.hpp
upb/reflection/message_def.h
diff --git a/cmake/libupb.cmake b/cmake/libupb.cmake
index c7c1eb24f0..6622429ca8 100644
--- a/cmake/libupb.cmake
+++ b/cmake/libupb.cmake
@@ -9,6 +9,9 @@ set(bootstrap_sources
${bootstrap_cmake_dir}/google/protobuf/descriptor.upb.h
${bootstrap_cmake_dir}/google/protobuf/descriptor.upb_minitable.h
${bootstrap_cmake_dir}/google/protobuf/descriptor.upb_minitable.c
+ ${bootstrap_cmake_dir}/google/protobuf/json_enumvalue_options.upb.h
+ ${bootstrap_cmake_dir}/google/protobuf/json_enumvalue_options.upb_minitable.h
+ ${bootstrap_cmake_dir}/google/protobuf/json_enumvalue_options.upb_minitable.c
)
# Note: upb does not support shared library builds, and is intended to be
diff --git a/csharp/BUILD.bazel b/csharp/BUILD.bazel
index b21428baa6..4bca560c65 100644
--- a/csharp/BUILD.bazel
+++ b/csharp/BUILD.bazel
@@ -15,7 +15,7 @@ load("//upb/cmake:build_defs.bzl", "staleness_test")
filegroup(
name = "c_sharp_features_proto_srcs",
srcs = ["google/protobuf/c_sharp_features.proto"],
- visibility = ["//:__subpackages__"],
+ visibility = ["//src/google/protobuf:__pkg__"],
)
proto_library(
diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index 2cb5ec03ff..ad7e1f64ec 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -5,7 +5,7 @@
Google Protocol Buffers tools
Tools for Protocol Buffers - Google's data interchange format.
See project site for more info.
- 3.36.0
+ 3.36.0-rc2
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 dcfb63c961..dd969f2416 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.36.0
+ 3.36.0-rc2
10.0
Google Inc.
netstandard2.0;net8.0
diff --git a/go/BUILD.bazel b/go/BUILD.bazel
index 3dfdd21c1d..7390cdc0c4 100644
--- a/go/BUILD.bazel
+++ b/go/BUILD.bazel
@@ -3,7 +3,7 @@ load("//bazel:proto_library.bzl", "proto_library")
filegroup(
name = "go_features_proto_srcs",
srcs = ["google/protobuf/go_features.proto"],
- visibility = ["//:__subpackages__"],
+ visibility = ["//src/google/protobuf:__pkg__"],
)
proto_library(
diff --git a/java/bom/pom.xml b/java/bom/pom.xml
index f9813ed0d0..427a52abf2 100644
--- a/java/bom/pom.xml
+++ b/java/bom/pom.xml
@@ -4,7 +4,7 @@
com.google.protobuf
protobuf-bom
- 4.36.0
+ 4.36.0-RC2
pom
Protocol Buffers [BOM]
diff --git a/java/core/BUILD.bazel b/java/core/BUILD.bazel
index f167846b8e..0502c5489f 100644
--- a/java/core/BUILD.bazel
+++ b/java/core/BUILD.bazel
@@ -192,7 +192,7 @@ proto_library(
"//:__pkg__",
"//editions:__pkg__",
"//java/__subpackages__",
- "//pkg:__pkg__",
+ "//src/google/protobuf:__pkg__",
],
deps = ["//:descriptor_proto"],
)
@@ -210,8 +210,8 @@ filegroup(
name = "java_features_proto_srcs",
srcs = ["src/main/resources/google/protobuf/java_features.proto"],
visibility = [
- "//pkg:__pkg__",
"//python:__pkg__",
+ "//src/google/protobuf:__pkg__",
],
)
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 d688f3a50e..c49f229c5e 100644
--- a/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java
+++ b/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java
@@ -30,7 +30,7 @@ public final class RuntimeVersion {
public static final int OSS_MAJOR = 4;
public static final int OSS_MINOR = 36;
public static final int OSS_PATCH = 0;
- public static final String OSS_SUFFIX = "-dev";
+ public static final String OSS_SUFFIX = "-rc2";
public static final RuntimeDomain DOMAIN = OSS_DOMAIN;
public static final int MAJOR = OSS_MAJOR;
diff --git a/java/kotlin/pom.xml b/java/kotlin/pom.xml
index 0dc1bc0496..263a7cf801 100644
--- a/java/kotlin/pom.xml
+++ b/java/kotlin/pom.xml
@@ -4,7 +4,7 @@
com.google.protobuf
protobuf-parent
- 4.36.0
+ 4.36.0-RC2
protobuf-kotlin
diff --git a/java/pom.xml b/java/pom.xml
index 8b714a8b14..c293bfce9c 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -4,7 +4,7 @@
com.google.protobuf
protobuf-parent
- 4.36.0
+ 4.36.0-RC2
pom
Protocol Buffers [Parent]
diff --git a/java/protoc/pom.xml b/java/protoc/pom.xml
index 5d2050f599..510bf80a67 100644
--- a/java/protoc/pom.xml
+++ b/java/protoc/pom.xml
@@ -8,7 +8,7 @@
com.google.protobuf
protoc
- 4.36.0
+ 4.36.0-RC2
pom
Protobuf Compiler
diff --git a/java/util/BUILD.bazel b/java/util/BUILD.bazel
index d633579b26..d2d5c0108f 100644
--- a/java/util/BUILD.bazel
+++ b/java/util/BUILD.bazel
@@ -1,16 +1,26 @@
load("@rules_java//java:java_library.bzl", "java_library")
-load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix")
+load("//:protobuf.bzl", "internal_gen_well_known_protos_java")
load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION")
load("//bazel:java_proto_library.bzl", "java_proto_library")
load("//bazel:proto_library.bzl", "proto_library")
load("//build_defs:java_opts.bzl", "protobuf_java_export", "protobuf_versioned_java_library")
load("//java/internal:testing.bzl", "junit_tests")
+internal_gen_well_known_protos_java(
+ name = "gen_language_neutral_protos_java",
+ deps = [
+ "//:json_enumvalue_options_proto",
+ "//:json_options_proto",
+ ],
+)
+
java_library(
name = "util",
srcs = glob([
"src/main/java/com/google/protobuf/util/*.java",
- ]),
+ ]) + [
+ ":gen_language_neutral_protos_java",
+ ],
visibility = ["//visibility:public"],
deps = [
"//java/core",
@@ -24,7 +34,9 @@ protobuf_versioned_java_library(
name = "util_bundle",
srcs = glob([
"src/main/java/com/google/protobuf/util/*.java",
- ]),
+ ]) + [
+ ":gen_language_neutral_protos_java",
+ ],
automatic_module_name = "com.google.protobuf.util",
bundle_description = "Utilities for Protocol Buffers",
bundle_name = "Protocol Buffers [Util]",
@@ -44,6 +56,9 @@ protobuf_java_export(
deploy_env = ["//java/core"],
maven_coordinates = "com.google.protobuf:protobuf-java-util:%s" % PROTOBUF_JAVA_VERSION,
pom_template = "pom_template.xml",
+ resources = [
+ "//src/google/protobuf:json_options_proto_srcs",
+ ],
tags = ["manual"],
visibility = ["//java:__pkg__"],
runtime_deps = [":util_bundle"],
@@ -63,6 +78,9 @@ filegroup(
proto_library(
name = "test_protos",
srcs = glob(["src/test/proto/**/*.proto"]),
+ option_deps = [
+ "//:json_options_proto",
+ ],
deps = [
"//:any_proto",
"//:duration_proto",
@@ -78,6 +96,12 @@ java_proto_library(
deps = [":test_protos"],
)
+java_proto_library(
+ name = "json_enumvalue_options_java_proto",
+ visibility = ["//visibility:public"],
+ deps = ["//:json_enumvalue_options_proto"],
+)
+
junit_tests(
name = "tests",
package_name = "com.google.protobuf.util",
diff --git a/java/util/generate-sources-build.xml b/java/util/generate-sources-build.xml
new file mode 100644
index 0000000000..c19809db70
--- /dev/null
+++ b/java/util/generate-sources-build.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
index d56371b559..89c49f2788 100644
--- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
+++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
@@ -1546,7 +1546,14 @@ public class JsonFormat {
if (printingEnumsAsInts || ((EnumValueDescriptor) value).getIndex() == -1) {
generator.print(String.valueOf(((EnumValueDescriptor) value).getNumber()));
} else {
- generator.print("\"" + ((EnumValueDescriptor) value).getName() + "\"");
+ EnumValueDescriptor enumValue = (EnumValueDescriptor) value;
+ JsonEnumValueOptions ext =
+ enumValue.getOptions().getExtension(JsonEnumvalueOptionsProto.json);
+ if (ext.hasString()) {
+ printStringEscapedAndQuoted(ext.getString());
+ } else {
+ generator.print("\"" + enumValue.getName() + "\"");
+ }
}
}
break;
@@ -1649,6 +1656,8 @@ public class JsonFormat {
private final int recursionLimit;
private final boolean legacyLenient;
private int currentDepth;
+ private final Map enumJsonNamesCache =
+ new HashMap<>();
ParserImpl(
com.google.protobuf.TypeRegistry registry,
@@ -2428,31 +2437,56 @@ public class JsonFormat {
@Nullable
private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json)
throws InvalidProtocolBufferException {
- String value = json.getAsString();
- EnumValueDescriptor result = enumDescriptor.findValueByName(value);
- if (result == null) {
- // Try to interpret the value as a number.
- try {
- int numericValue = parseInt32(json);
- if (enumDescriptor.isClosed()) {
- result = enumDescriptor.findValueByNumber(numericValue);
- } else {
- result = enumDescriptor.findValueByNumberCreatingIfUnknown(numericValue);
- }
- } catch (InvalidProtocolBufferException e) {
- // Fall through. This exception is about invalid int32 value we get from parseInt32() but
- // that's not the exception we want the user to see. Since result == null, we will throw
- // an exception later.
- }
+ // Calling json.getAsString() works for both JsonPrimitive and single-element JsonArray (e.g.,
+ // ["FOO"] or [2]), throwing UnsupportedOperationException/IllegalStateException for other
+ // structures.
+ final String name;
+ try {
+ name = json.getAsString();
+ } catch (UnsupportedOperationException | IllegalStateException e) {
+ // UnsupportedOperationException is thrown by Gson when getAsString() is called on a
+ // JsonObject (e.g., "{}") or JsonNull (e.g., "null"). IllegalStateException is thrown when
+ // getAsString() is called on a JsonArray whose length is not exactly 1 (e.g., "[]" or
+ // '["FOO", "BAR"]').
+ throw new InvalidProtocolBufferException(
+ "Invalid enum value: " + json + " for enum type: " + enumDescriptor.getFullName(), e);
+ }
- // todo(elharo): if we are ignoring unknown fields, shouldn't we still
- // throw InvalidProtocolBufferException for a non-numeric value here?
- if (result == null && !ignoringUnknownFields) {
- throw new InvalidProtocolBufferException(
- "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName());
+ EnumValueDescriptor result = enumDescriptor.findValueByName(name);
+ if (result != null) {
+ return result;
+ }
+
+ // Custom JSON string lookup is restricted strictly to string primitives, explicitly
+ // rejecting single-element arrays of custom names (e.g., ["custom_enum_name"]).
+ if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isString()) {
+ AlternativeEnumJsonNames enumJsonNames =
+ enumJsonNamesCache.computeIfAbsent(enumDescriptor, AlternativeEnumJsonNames::new);
+ result = enumJsonNames.map.get(name);
+ if (result != null) {
+ return result;
}
}
- return result;
+ try {
+ int numericValue = parseInt32(json);
+ result =
+ enumDescriptor.isClosed()
+ ? enumDescriptor.findValueByNumber(numericValue)
+ : enumDescriptor.findValueByNumberCreatingIfUnknown(numericValue);
+ if (result != null) {
+ return result;
+ }
+ } catch (InvalidProtocolBufferException e) {
+ // Fall through when json is not a valid int32 value (e.g., when json is a string like
+ // "XXX" or boolean true).
+ }
+ // todo(elharo): if we are ignoring unknown fields, shouldn't we still
+ // throw InvalidProtocolBufferException for a non-numeric value here?
+ if (!ignoringUnknownFields) {
+ throw new InvalidProtocolBufferException(
+ "Invalid enum value: " + json + " for enum type: " + enumDescriptor.getFullName());
+ }
+ return null;
}
@SuppressWarnings("AvoidValueSetter")
@@ -2533,5 +2567,20 @@ public class JsonFormat {
throw new InvalidProtocolBufferException("Invalid field type: " + field.getType());
}
}
+
+ private static final class AlternativeEnumJsonNames {
+ final Map map;
+
+ AlternativeEnumJsonNames(EnumDescriptor enumDescriptor) {
+ Map m = new HashMap<>();
+ for (EnumValueDescriptor ev : enumDescriptor.getValues()) {
+ JsonEnumValueOptions ext = ev.getOptions().getExtension(JsonEnumvalueOptionsProto.json);
+ if (ext.hasString()) {
+ m.put(ext.getString(), ev);
+ }
+ }
+ this.map = Collections.unmodifiableMap(m);
+ }
+ }
}
}
diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
index 86a13419f7..dc9b3de92b 100644
--- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
@@ -38,6 +38,8 @@ import com.google.protobuf.UInt32Value;
import com.google.protobuf.UInt64Value;
import com.google.protobuf.Value;
import com.google.protobuf.util.JsonFormat.TypeRegistry;
+import com.google.protobuf.util.proto.Armor;
+import com.google.protobuf.util.proto.Helmet;
import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes;
import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes.AliasedEnum;
import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes.NestedEnum;
@@ -54,6 +56,7 @@ import com.google.protobuf.util.proto.JsonTestProto.TestTimestamp;
import com.google.protobuf.util.proto.JsonTestProto.TestWrappers;
import com.google.protobuf.util.proto.JsonTestProto2;
import com.google.protobuf.util.proto.JsonTestProto2.TestAllTypesProto2;
+import com.google.protobuf.util.proto.Knight;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -2714,4 +2717,207 @@ public class JsonFormatTest {
assertThat(builder.getInt32ToStringMapMap()).containsEntry(3, "baz");
assertThat(builder.getInt32ToStringMapMap()).hasSize(3);
}
+
+ @Test
+ public void gorgetDefaultSerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GORGET).build();
+ assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_GORGET);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"armor\":\"ARMOR_GORGET\"}");
+ }
+
+ @Test
+ public void greatHelmSerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GREAT_HELM).build();
+ assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_GREAT_HELM);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"armor\":\"gr8 helm\"}");
+ }
+
+ @Test
+ public void gauntletSerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GAUNTLET).build();
+ assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_GAUNTLET);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"armor\":\"a\\\"b\"}");
+ }
+
+ @Test
+ public void doubleQuoteEnumSerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_PLATE).build();
+ assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_PLATE);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"armor\":\"\\\"plate\\\"\"}");
+ }
+
+ @Test
+ public void coifEmptySerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_COIF).build();
+ assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_COIF);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"armor\":\"\"}");
+ }
+
+ @Test
+ public void helmetEmptyOptionSerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setHelmet(Helmet.HELMET_GOBLIN).build();
+ assertThat(msg.getHelmet()).isEqualTo(Helmet.HELMET_GOBLIN);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"helmet\":\"HELMET_GOBLIN\"}");
+ }
+
+ @Test
+ public void pauldronEscapingSerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_PAULDRON).build();
+ assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_PAULDRON);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"armor\":\"p\\taul\\ndron\"}");
+ }
+
+ @Test
+ public void hachiMaiDoSerialization() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_HACHI_MAI_DO).build();
+ assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_HACHI_MAI_DO);
+
+ String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg);
+
+ assertThat(jsonRes).isEqualTo("{\"armor\":\"8\"}");
+ }
+
+ @Test
+ public void greatHelmIntOverride() throws Exception {
+ Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GREAT_HELM).build();
+
+ String jsonRes =
+ JsonFormat.printer().omittingInsignificantWhitespace().printingEnumsAsInts().print(msg);
+
+ // Integer overrides always win.
+ assertThat(jsonRes).isEqualTo("{\"armor\":1}");
+ }
+
+ // --- Parser Tests ---
+
+ @Test
+ public void greatHelmParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"gr8 helm\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_GREAT_HELM);
+ }
+
+ @Test
+ public void greatHelmRawNameParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"ARMOR_GREAT_HELM\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_GREAT_HELM);
+ }
+
+ @Test
+ public void gauntletParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"a\\\"b\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_GAUNTLET);
+ }
+
+ @Test
+ public void doubleQuoteEnumParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"\\\"plate\\\"\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_PLATE);
+ }
+
+ @Test
+ public void coifEmptyParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_COIF);
+ }
+
+ @Test
+ public void helmetEmptyOptionParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"helmet\":\"HELMET_GOBLIN\"}", builder);
+ assertThat(builder.getHelmet()).isEqualTo(Helmet.HELMET_GOBLIN);
+ }
+
+ @Test
+ public void helmetEmptyStringParsingFails() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ assertThrows(
+ InvalidProtocolBufferException.class,
+ () -> JsonFormat.parser().merge("{\"helmet\":\"\"}", builder));
+ }
+
+ @Test
+ public void pauldronEscapingParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"p\\taul\\ndron\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_PAULDRON);
+ }
+
+ @Test
+ public void hachiMaiDoParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"8\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_HACHI_MAI_DO);
+ }
+
+ @Test
+ public void hachiMaiDoIntParsing() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":8}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_HACHI_MAI_DO);
+ }
+
+ @Test
+ public void parseCustomStringTrue() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ JsonFormat.parser().merge("{\"armor\":\"true\"}", builder);
+ assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_SHIELD);
+ }
+
+ @Test
+ public void parseCustomStringSingleElementArrayFails() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ assertThrows(
+ InvalidProtocolBufferException.class,
+ () -> JsonFormat.parser().merge("{\"armor\":[\"gr8 helm\"]}", builder));
+ }
+
+ @Test
+ public void parseCustomStringTrueAsBooleanFails() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ assertThrows(
+ InvalidProtocolBufferException.class,
+ () -> JsonFormat.parser().merge("{\"armor\":true}", builder));
+ }
+
+ @Test
+ public void caseInsensitiveGauntletParsingFails() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ assertThrows(
+ InvalidProtocolBufferException.class,
+ () -> JsonFormat.parser().merge("{\"armor\":\"A\\\"b\"}", builder));
+ }
+
+ @Test
+ public void caseInsensitiveGauntletRawNameParsingFails() throws Exception {
+ Knight.Builder builder = Knight.newBuilder();
+ assertThrows(
+ InvalidProtocolBufferException.class,
+ () -> JsonFormat.parser().merge("{\"armor\":\"armor_GAUNtlet\"}", builder));
+ }
}
diff --git a/java/util/src/test/proto/com/google/protobuf/util/json_test_custom_enum_string.proto b/java/util/src/test/proto/com/google/protobuf/util/json_test_custom_enum_string.proto
new file mode 100644
index 0000000000..8229b28cc8
--- /dev/null
+++ b/java/util/src/test/proto/com/google/protobuf/util/json_test_custom_enum_string.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2026 Google LLC. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+// Tests custom JSON string representation for enum values
+// ((pb.enumvalue.json).string).
+edition = "2026";
+
+package com.google.protobuf.util.json_test_custom_enum_string;
+
+import option "google/protobuf/json_options.proto";
+
+option java_package = "com.google.protobuf.util.proto";
+
+enum Armor {
+ ARMOR_UNKNOWN = 0;
+ ARMOR_GREAT_HELM = 1 [(pb.enumvalue.json).string = "gr8 helm"];
+ ARMOR_GORGET = 2;
+ ARMOR_GAUNTLET = 3 [(pb.enumvalue.json).string = "a\"b"];
+ ARMOR_PLATE = 4 [(pb.enumvalue.json).string = "\"plate\""];
+ ARMOR_COIF = 5 [(pb.enumvalue.json).string = ""];
+ ARMOR_PAULDRON = 6 [(pb.enumvalue.json).string = "p\taul\ndron"];
+ ARMOR_SHIELD = 7 [(pb.enumvalue.json).string = "true"];
+ ARMOR_HACHI_MAI_DO = 8 [(pb.enumvalue.json).string = "8"];
+}
+
+enum Helmet {
+ HELMET_UNKNOWN = 0;
+ HELMET_GOBLIN = 1 [(pb.enumvalue.json) = {}];
+}
+
+message Knight {
+ Armor armor = 1;
+ Helmet helmet = 2;
+}
diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c
index 60c98d276e..be8a4f658c 100644
--- a/php/ext/google/protobuf/php-upb.c
+++ b/php/ext/google/protobuf/php-upb.c
@@ -38,6 +38,13 @@
#define UPB_GNUC_MIN(x, y) 0
#endif
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define UPB_CLANG_MIN(x, y) \
+ (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
+#else
+#define UPB_CLANG_MIN(x, y) 0
+#endif
+
// Macros for checking for compiler attributes, defined here to avoid the
// problem described in
// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html.
@@ -602,10 +609,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name; \
- extern type __stop_linkarr_##name; \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name; \
+ extern type __stop_linkarr_##name; \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -616,13 +625,15 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name __asm( \
- "section$start$__DATA$__la_" #name); \
- extern type __stop_linkarr_##name __asm( \
- "section$end$__DATA$" \
- "__la_" #name); \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name __asm( \
+ "section$start$__DATA$__la_" #name); \
+ extern type __stop_linkarr_##name __asm( \
+ "section$end$__DATA$" \
+ "__la_" #name); \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -660,7 +671,9 @@ Error, UINTPTR_MAX is undefined
// Linker arrays are not supported on this platform. Make macros no-ops.
#define UPB_LINKARR_APPEND(name)
-#define UPB_LINKARR_DECLARE(name, type)
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)")
#define UPB_LINKARR_START(name) (NULL)
#define UPB_LINKARR_STOP(name) (NULL)
@@ -677,11 +690,46 @@ Error, UINTPTR_MAX is undefined
#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name)
#endif
-#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define _UPB_STRINGIFY2(x) #x
+#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x)
+
+#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1))
+/*
+ * Workaround for b/456308964 and b/456317163. Although weak constructors
+ * resolve to a single function body, Clang still emits a pointer into
+ * .init_array for every translation unit, causing the constructor to be
+ * executed multiple times and inflating binary size. We wrap the .init_array
+ * entry in a COMDAT group (using inline assembly) to force the linker to
+ * deduplicate the pointer to exactly one instance. %cc is used in preference to
+ * the more widely available %c because %c may under some circumstances still
+ * output a function name including relocation information, which will then
+ * confuse the linker. This was only a problem on gcc; when %cc was introduced
+ * to clang it was just an alias to %c, and clang's %c had already done the
+ * checks that %cc introduced to gcc.
+ * References:
+ * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa
+ * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305
+ */
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
+ __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \
+ void) { \
+ __asm__ volatile( \
+ ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \
+ ".dc.a %cc0\n" \
+ ".popsection\n" \
+ : \
+ : "X"(UPB_PRIVATE(name))); \
+ __VA_ARGS__ \
+ }
+#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \
+ defined(__MINGW32__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
_UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
__attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \
- name)(void)
+ name)(void) { \
+ __VA_ARGS__ \
+ }
#elif defined(_MSC_VER)
/*
* See: https://stackoverflow.com/questions/1113409
@@ -692,17 +740,22 @@ Error, UINTPTR_MAX is undefined
* create a dummy exported weak symbol that prevent this stripping.
*/
#pragma section(".CRT$XCT", read)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
static void __cdecl UPB_PRIVATE(name)(void); \
__declspec(allocate(".CRT$XCT"), selectany) void( \
__cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \
__declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \
&UPB_PRIVATE(name##_); \
- static void __cdecl UPB_PRIVATE(name)(void)
-
+ static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ }
#else
// No constructor support, nothing we can do except not break builds.
-#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void)
+#if defined(__GNUC__) || defined(__clang__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#else
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#endif
#endif
//
@@ -740,9 +793,9 @@ Error, UINTPTR_MAX is undefined
#elif defined(__ELF__) || defined(__wasm__)
-// On ELF, weak aliases work properly, so we can have all weak MiniTables point
-// to the same empty singleton MiniTable. This reduces code size if many
-// MiniTables are tree shaken.
+ // On ELF, weak aliases work properly, so we can have all weak MiniTables
+ // point to the same empty singleton MiniTable. This reduces code size if many
+ // MiniTables are tree shaken.
#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \
__attribute__((weak)) \
const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \
@@ -2389,7 +2442,7 @@ const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init = {
},
};
-static const upb_MiniTable *messages_layout[35] = {
+static const upb_MiniTable *messages_layout_google_protobuf_descriptor_proto_upb_file_layout[35] = {
&google__protobuf__FileDescriptorSet_msg_init,
&google__protobuf__FileDescriptorProto_msg_init,
&google__protobuf__DescriptorProto_msg_init,
@@ -2427,7 +2480,7 @@ static const upb_MiniTable *messages_layout[35] = {
&google__protobuf__GeneratedCodeInfo__Annotation_msg_init,
};
-static const upb_MiniTableEnum *enums_layout[21] = {
+static const upb_MiniTableEnum *enums_layout_google_protobuf_descriptor_proto_upb_file_layout[21] = {
&google__protobuf__Edition_enum_init,
&google__protobuf__ExtensionRangeOptions__VerificationState_enum_init,
&google__protobuf__FeatureSet__EnforceNamingStyle_enum_init,
@@ -2452,8 +2505,8 @@ static const upb_MiniTableEnum *enums_layout[21] = {
};
const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = {
- messages_layout,
- enums_layout,
+ messages_layout_google_protobuf_descriptor_proto_upb_file_layout,
+ enums_layout_google_protobuf_descriptor_proto_upb_file_layout,
NULL,
35,
21,
@@ -2471,7 +2524,7 @@ const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = {
-static const char descriptor[14056] = {
+static const char descriptor_google_protobuf_descriptor_proto_upbdefinit[14056] = {
'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o',
't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i',
'p', 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017',
@@ -3646,15 +3699,142 @@ static const char descriptor[14056] = {
't', 'i', 'o', 'n',
};
-static _upb_DefPool_Init *deps[1] = {
+static _upb_DefPool_Init* deps_google_protobuf_descriptor_proto_upbdefinit[1] = {
NULL,
};
_upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit = {
- deps,
+ deps_google_protobuf_descriptor_proto_upbdefinit,
&google_protobuf_descriptor_proto_upb_file_layout,
"google/protobuf/descriptor.proto",
- UPB_STRINGVIEW_INIT(descriptor, sizeof(descriptor)),
+ UPB_STRINGVIEW_INIT(descriptor_google_protobuf_descriptor_proto_upbdefinit,
+ sizeof(descriptor_google_protobuf_descriptor_proto_upbdefinit)),
+};
+
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#include
+
+// Must be last.
+
+extern const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* UPB_PRIVATE(upb_generated_extension_list);
+typedef struct {
+ upb_MiniTableField fields[1];
+} pb__enumvalue__JsonEnumValueOptions_msg_init_Fields;
+
+static const pb__enumvalue__JsonEnumValueOptions_msg_init_Fields pb_enumvalue_JsonEnumValueOptions__fields = {{
+ {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
+}};
+
+const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init = {
+ &pb_enumvalue_JsonEnumValueOptions__fields.fields[0],
+ UPB_SIZE(24, 32), 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(8), 0,
+#ifdef UPB_TRACING_ENABLED
+ "pb.enumvalue.JsonEnumValueOptions",
+#endif
+ UPB_FASTTABLE_INIT({
+ {0x0000000000000000, &_upb_FastDecoder_DecodeUnknown},
+ {0x001000000000000a, &upb_DecodeFast_String_Scalar_Tag1Byte},
+ })
+};
+
+static const upb_MiniTableExtension pb_enumvalue_json_ext_obj = {
+ {998, 0, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsExtension | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
+ {.UPB_PRIVATE(submsg) = &pb__enumvalue__JsonEnumValueOptions_msg_init},
+ &google__protobuf__EnumValueOptions_msg_init,
+
+};
+UPB_LINKARR_APPEND(upb_AllExts)
+const upb_MiniTableExtension* pb_enumvalue_json_ext = &pb_enumvalue_json_ext_obj;
+ static const upb_MiniTable *messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = {
+ &pb__enumvalue__JsonEnumValueOptions_msg_init,
+};
+
+
+static const upb_MiniTableExtension *extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = {
+ &pb_enumvalue_json_ext_obj,
+};
+
+UPB_LINKARR_DECLARE(upb_AllExts, const upb_MiniTableExtension*);
+UPB_CONSTRUCTOR(upb_GeneratedRegistry_Constructor, google_protobuf_json_enumvalue_options_proto_ext_constructor, {
+ static bool finished = false;
+ if (finished) return;
+ finished = true;
+ static UPB_PRIVATE(upb_GeneratedExtensionListEntry) entry = {
+ UPB_LINKARR_START(upb_AllExts),
+ UPB_LINKARR_STOP(upb_AllExts),
+ NULL
+ };
+ UPB_ASSERT(entry.next == NULL);
+ entry.next = UPB_PRIVATE(upb_generated_extension_list);
+ UPB_PRIVATE(upb_generated_extension_list) = &entry;
+})
+const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout = {
+ messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout,
+ NULL,
+ extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout,
+ 1,
+ 0,
+ 1,
+};
+
+
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+
+
+extern _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit;
+
+static const char descriptor_google_protobuf_json_enumvalue_options_proto_upbdefinit[285] = {
+ '\n', ',', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o',
+ 't', 'o', 'b', 'u', 'f', '/', 'j', 's', 'o', 'n', '_', 'e',
+ 'n', 'u', 'm', 'v', 'a', 'l', 'u', 'e', '_', 'o', 'p', 't',
+ 'i', 'o', 'n', 's', '.', 'p', 'r', 'o', 't', 'o', '\022', '\014',
+ 'p', 'b', '.', 'e', 'n', 'u', 'm', 'v', 'a', 'l', 'u', 'e',
+ '\032', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o',
+ 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i',
+ 'p', 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\"', '0',
+ '\n', '\024', 'J', 's', 'o', 'n', 'E', 'n', 'u', 'm', 'V', 'a',
+ 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\026',
+ '\n', '\006', 's', 't', 'r', 'i', 'n', 'g', '\030', '\001', ' ', '\001',
+ '(', '\t', 'R', '\006', 's', 't', 'r', 'i', 'n', 'g', 'X', '\001',
+ ':', 'b', '\n', '\004', 'j', 's', 'o', 'n', '\022', '!', '.', 'g',
+ 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b',
+ 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e',
+ 'O', 'p', 't', 'i', 'o', 'n', 's', '\030', '\346', '\007', ' ', '\001',
+ '(', '\013', '2', '\"', '.', 'p', 'b', '.', 'e', 'n', 'u', 'm',
+ 'v', 'a', 'l', 'u', 'e', '.', 'J', 's', 'o', 'n', 'E', 'n',
+ 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o',
+ 'n', 's', 'B', '\006', '\262', '\001', '\003', '\010', '\352', '\007', 'R', '\004',
+ 'j', 's', 'o', 'n', 'B', '\032', '\n', '\030', 'c', 'o', 'm', '.',
+ 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o',
+ 'b', 'u', 'f', '.', 'u', 't', 'i', 'l', 'b', '\010', 'e', 'd',
+ 'i', 't', 'i', 'o', 'n', 's', 'p', '\351', '\007',
+};
+
+static _upb_DefPool_Init* deps_google_protobuf_json_enumvalue_options_proto_upbdefinit[2] = {
+ &google_protobuf_descriptor_proto_upbdefinit,
+ NULL,
+};
+
+_upb_DefPool_Init google_protobuf_json_enumvalue_options_proto_upbdefinit = {
+ deps_google_protobuf_json_enumvalue_options_proto_upbdefinit,
+ &google_protobuf_json_enumvalue_options_proto_upb_file_layout,
+ "google/protobuf/json_enumvalue_options.proto",
+ UPB_STRINGVIEW_INIT(descriptor_google_protobuf_json_enumvalue_options_proto_upbdefinit,
+ sizeof(descriptor_google_protobuf_json_enumvalue_options_proto_upbdefinit)),
};
@@ -5403,7 +5583,7 @@ static upb_JsonMessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) {
upb_StringView str = jsondec_string(d);
const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f);
const upb_EnumValueDef* ev =
- upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size);
+ upb_EnumDef_FindByJsonNameWithSize(e, str.data, str.size);
upb_JsonMessageValue val = {.ignore = false};
if (ev) {
val.value.int32_val = upb_EnumValueDef_Number(ev);
@@ -6181,11 +6361,12 @@ int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size,
}
-#include
#include
#include
#include
+#include
#include
+#include
#include
@@ -6212,6 +6393,7 @@ static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg,
const upb_MessageDef* m, bool first);
static void jsonenc_value(jsonenc* e, const upb_Message* msg,
const upb_MessageDef* m);
+static void jsonenc_string(jsonenc* e, upb_StringView str);
UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) {
upb_Status_SetErrorMessage(e->status, msg);
@@ -6373,7 +6555,8 @@ static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) {
: upb_EnumDef_FindValueByNumber(e_def, val);
if (ev) {
- jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev));
+ const char* name = upb_EnumValueDef_JsonName(ev);
+ jsonenc_string(e, upb_StringView_FromString(name));
} else {
jsonenc_printf(e, "%" PRId32, val);
}
@@ -12710,6 +12893,28 @@ struct upb_EnumDef {
bool is_sorted; // Whether all of the values are defined in ascending order.
};
+// We store both regular proto enum names and custom JSON enum names in the
+// same strtable (ntoi). This is safe because protoc enforces that custom JSON
+// enum names never conflict with default enum names across different enum
+// values (or are identical, in which case we leave the entry untagged). Because
+// upb_EnumValueDef pointers are arena-aligned to at least 4 bytes (bit 0 is
+// always 0 for untagged pointers), we set bit 0 to tag custom JSON-only names
+// so that regular name lookups can ignore them.
+static const uintptr_t kUpb_EnumDef_JsonOnlyTag = 1ULL;
+
+static upb_value _upb_EnumDef_TagJsonOnly(upb_value v) {
+ v.val |= kUpb_EnumDef_JsonOnlyTag;
+ return v;
+}
+
+static bool _upb_EnumDef_IsJsonOnly(upb_value v) {
+ return (v.val & kUpb_EnumDef_JsonOnlyTag) != 0;
+}
+
+static const upb_EnumValueDef* _upb_EnumDef_Untag(upb_value v) {
+ return (const upb_EnumValueDef*)(v.val & ~kUpb_EnumDef_JsonOnlyTag);
+}
+
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) {
return (upb_EnumDef*)&e[i];
}
@@ -12718,18 +12923,43 @@ const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) {
return e->layout;
}
-bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) {
+void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e,
+ upb_EnumValueDef* v) {
const char* name = upb_EnumValueDef_Name(v);
const upb_value val = upb_value_constptr(v);
- bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a);
- if (!ok) return false;
+ bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, ctx->arena);
+ if (!ok) _upb_DefBuilder_OomErr(ctx);
- // Multiple enumerators can have the same number, first one wins.
+ // Aliased enum values can share the same custom JSON name, first one wins.
+ const char* json_name = upb_EnumValueDef_JsonName(v);
+ size_t json_len = strlen(json_name);
+ if (strcmp(json_name, name) != 0) {
+ upb_value existing_value;
+ if (upb_strtable_lookup2(&e->ntoi, json_name, json_len, &existing_value)) {
+ const upb_EnumValueDef* enumval = _upb_EnumDef_Untag(existing_value);
+ if (upb_EnumValueDef_Number(enumval) != upb_EnumValueDef_Number(v)) {
+ // If the custom JSON name exists, but points to a value with a
+ // different number, then this is a parse/conflict error.
+ _upb_DefBuilder_Errf(ctx,
+ "duplicate custom json_name (%s) in enum (%s)",
+ json_name, upb_EnumDef_FullName(e));
+ }
+ } else {
+ upb_value json_val = _upb_EnumDef_TagJsonOnly(val);
+ if (!upb_strtable_insert(&e->ntoi, json_name, json_len, json_val,
+ ctx->arena)) {
+ _upb_DefBuilder_OomErr(ctx);
+ }
+ }
+ }
+
+ // Multiple enum values can have the same number, first one wins.
const int number = upb_EnumValueDef_Number(v);
if (!upb_inttable_lookup(&e->iton, number, NULL)) {
- return upb_inttable_insert(&e->iton, number, val, a);
+ if (!upb_inttable_insert(&e->iton, number, val, ctx->arena)) {
+ _upb_DefBuilder_OomErr(ctx);
+ }
}
- return true;
}
const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) {
@@ -12786,6 +13016,16 @@ upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) {
int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; }
+const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(const upb_EnumDef* e,
+ const char* name,
+ size_t size) {
+ upb_value v;
+ if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) {
+ return NULL;
+ }
+ return _upb_EnumDef_Untag(v);
+}
+
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const char* name) {
return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name));
@@ -12794,9 +13034,13 @@ const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
const upb_EnumDef* e, const char* name, size_t size) {
upb_value v;
- return upb_strtable_lookup2(&e->ntoi, name, size, &v)
- ? upb_value_getconstptr(v)
- : NULL;
+ if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) {
+ return NULL;
+ }
+ if (_upb_EnumDef_IsJsonOnly(v)) {
+ return NULL;
+ }
+ return upb_value_getconstptr(v);
}
const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e,
@@ -12937,7 +13181,7 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix,
upb_EnumDef_FullName(e));
}
- bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena);
+ bool ok = upb_strtable_init(&e->ntoi, n_value * 2, ctx->arena);
if (!ok) _upb_DefBuilder_OomErr(ctx);
ok = upb_inttable_init(&e->iton, ctx->arena);
@@ -13054,6 +13298,7 @@ struct upb_EnumValueDef {
const google_protobuf_FeatureSet* resolved_features;
const upb_EnumDef* parent;
const char* full_name;
+ const char* json_name;
int32_t number;
};
@@ -13075,7 +13320,7 @@ const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v,
(upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*));
if (!out) return NULL;
- for (int i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
out[i] = (upb_EnumValueDef*)&v[i];
}
qsort(out, n, sizeof(void*), _upb_EnumValueDef_Compare);
@@ -13105,6 +13350,10 @@ const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) {
return v->full_name;
}
+const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v) {
+ return v->json_name ? v->json_name : upb_EnumValueDef_Name(v);
+}
+
const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) {
return _upb_DefBuilder_FullToShort(v->full_name);
}
@@ -13116,6 +13365,19 @@ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) {
return v - upb_EnumDef_Value(v->parent, 0);
}
+static const char* _upb_EnumValueDef_ExtractJsonName(
+ upb_DefBuilder* ctx, const upb_EnumValueDef* v) {
+ if (!upb_EnumValueDef_HasOptions(v)) return NULL;
+ const google_protobuf_EnumValueOptions* opts = (const google_protobuf_EnumValueOptions*)v->opts;
+ if (!pb_enumvalue_has_json(opts)) return NULL;
+ const pb_enumvalue_JsonEnumValueOptions* json_opts = pb_enumvalue_json(opts);
+ if (!json_opts || !pb_enumvalue_JsonEnumValueOptions_has_string(json_opts)) {
+ return NULL;
+ }
+ upb_StringView str = pb_enumvalue_JsonEnumValueOptions_string(json_opts);
+ return upb_strdup2(str.data, str.size, ctx->arena);
+}
+
static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_EnumValueDescriptorProto* val_proto,
const google_protobuf_FeatureSet* parent_features,
@@ -13130,11 +13392,11 @@ static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix,
v->parent = e; // Must happen prior to _upb_DefBuilder_Add()
v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto);
+ v->json_name = _upb_EnumValueDef_ExtractJsonName(ctx, v);
_upb_DefBuilder_Add(ctx, v->full_name,
_upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL));
- bool ok = _upb_EnumDef_Insert(e, v, ctx->arena);
- if (!ok) _upb_DefBuilder_OomErr(ctx);
+ _upb_EnumDef_Insert(ctx, e, v);
}
// Allocate and initialize an array of |n| enum value defs owned by |e|.
@@ -19094,6 +19356,7 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
#undef UPB_TSAN
#undef UPB_DEPRECATED
#undef UPB_GNUC_MIN
+#undef UPB_CLANG_MIN
#undef UPB_DESCRIPTOR_UPB_H_FILENAME
#undef UPB_DESC_MINITABLE
#undef UPB_IS_GOOGLE3
@@ -19120,3 +19383,6 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
#undef UPB_DEPRECATE_AND_INLINE
#undef UPB_MAYBE_ASSUME
#undef UPB_ATTR_CONST
+#undef _UPB_STRINGIFY
+#undef _UPB_STRINGIFY2
+#undef UPB_CONSTRUCTOR
diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h
index dd943a7f14..f431b86a71 100644
--- a/php/ext/google/protobuf/php-upb.h
+++ b/php/ext/google/protobuf/php-upb.h
@@ -37,6 +37,13 @@
#define UPB_GNUC_MIN(x, y) 0
#endif
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define UPB_CLANG_MIN(x, y) \
+ (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
+#else
+#define UPB_CLANG_MIN(x, y) 0
+#endif
+
// Macros for checking for compiler attributes, defined here to avoid the
// problem described in
// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html.
@@ -601,10 +608,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name; \
- extern type __stop_linkarr_##name; \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name; \
+ extern type __stop_linkarr_##name; \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -615,13 +624,15 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name __asm( \
- "section$start$__DATA$__la_" #name); \
- extern type __stop_linkarr_##name __asm( \
- "section$end$__DATA$" \
- "__la_" #name); \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name __asm( \
+ "section$start$__DATA$__la_" #name); \
+ extern type __stop_linkarr_##name __asm( \
+ "section$end$__DATA$" \
+ "__la_" #name); \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -659,7 +670,9 @@ Error, UINTPTR_MAX is undefined
// Linker arrays are not supported on this platform. Make macros no-ops.
#define UPB_LINKARR_APPEND(name)
-#define UPB_LINKARR_DECLARE(name, type)
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)")
#define UPB_LINKARR_START(name) (NULL)
#define UPB_LINKARR_STOP(name) (NULL)
@@ -676,11 +689,46 @@ Error, UINTPTR_MAX is undefined
#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name)
#endif
-#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define _UPB_STRINGIFY2(x) #x
+#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x)
+
+#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1))
+/*
+ * Workaround for b/456308964 and b/456317163. Although weak constructors
+ * resolve to a single function body, Clang still emits a pointer into
+ * .init_array for every translation unit, causing the constructor to be
+ * executed multiple times and inflating binary size. We wrap the .init_array
+ * entry in a COMDAT group (using inline assembly) to force the linker to
+ * deduplicate the pointer to exactly one instance. %cc is used in preference to
+ * the more widely available %c because %c may under some circumstances still
+ * output a function name including relocation information, which will then
+ * confuse the linker. This was only a problem on gcc; when %cc was introduced
+ * to clang it was just an alias to %c, and clang's %c had already done the
+ * checks that %cc introduced to gcc.
+ * References:
+ * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa
+ * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305
+ */
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
+ __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \
+ void) { \
+ __asm__ volatile( \
+ ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \
+ ".dc.a %cc0\n" \
+ ".popsection\n" \
+ : \
+ : "X"(UPB_PRIVATE(name))); \
+ __VA_ARGS__ \
+ }
+#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \
+ defined(__MINGW32__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
_UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
__attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \
- name)(void)
+ name)(void) { \
+ __VA_ARGS__ \
+ }
#elif defined(_MSC_VER)
/*
* See: https://stackoverflow.com/questions/1113409
@@ -691,17 +739,22 @@ Error, UINTPTR_MAX is undefined
* create a dummy exported weak symbol that prevent this stripping.
*/
#pragma section(".CRT$XCT", read)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
static void __cdecl UPB_PRIVATE(name)(void); \
__declspec(allocate(".CRT$XCT"), selectany) void( \
__cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \
__declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \
&UPB_PRIVATE(name##_); \
- static void __cdecl UPB_PRIVATE(name)(void)
-
+ static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ }
#else
// No constructor support, nothing we can do except not break builds.
-#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void)
+#if defined(__GNUC__) || defined(__clang__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#else
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#endif
#endif
//
@@ -739,9 +792,9 @@ Error, UINTPTR_MAX is undefined
#elif defined(__ELF__) || defined(__wasm__)
-// On ELF, weak aliases work properly, so we can have all weak MiniTables point
-// to the same empty singleton MiniTable. This reduces code size if many
-// MiniTables are tree shaken.
+ // On ELF, weak aliases work properly, so we can have all weak MiniTables
+ // point to the same empty singleton MiniTable. This reduces code size if many
+ // MiniTables are tree shaken.
#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \
__attribute__((weak)) \
const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \
@@ -14902,6 +14955,7 @@ bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s);
#include
#include
+#include
// Must be last.
@@ -14914,6 +14968,12 @@ bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num);
const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e);
int32_t upb_EnumDef_Default(const upb_EnumDef* e);
UPB_API const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e);
+UPB_API const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(
+ const upb_EnumDef* e, const char* name, size_t size);
+UPB_INLINE const upb_EnumValueDef* upb_EnumDef_FindByJsonName(
+ const upb_EnumDef* e, const char* name) {
+ return upb_EnumDef_FindByJsonNameWithSize(e, name, strlen(name));
+}
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const char* name);
UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
@@ -14956,6 +15016,8 @@ UPB_API int upb_EnumDef_ValueCount(const upb_EnumDef* e);
#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_
#define UPB_REFLECTION_ENUM_VALUE_DEF_H_
+#include
+
// Must be last.
@@ -14967,6 +15029,7 @@ const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v);
const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v);
bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v);
uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v);
+UPB_API const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v);
UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v);
UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v);
const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options(
@@ -15651,6 +15714,68 @@ UPB_INLINE const upb_MessageDef *google_protobuf_GeneratedCodeInfo_Annotation_ge
#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPBDEFS_H_ */
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_
+
+
+// Must be last.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init;
+extern const upb_MiniTableExtension* pb_enumvalue_json_ext;
+
+extern const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ */
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPBDEFS_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPBDEFS_H_
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern _upb_DefPool_Init google_protobuf_json_enumvalue_options_proto_upbdefinit;
+
+UPB_INLINE const upb_MessageDef *pb_enumvalue_JsonEnumValueOptions_getmsgdef(upb_DefPool *s) {
+ _upb_DefPool_LoadDefInit(s, &google_protobuf_json_enumvalue_options_proto_upbdefinit);
+ return upb_DefPool_FindMessageByName(s, "pb.enumvalue.JsonEnumValueOptions");
+}
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPBDEFS_H_ */
#ifndef UPB_BASE_INTERNAL_LOG2_H_
#define UPB_BASE_INTERNAL_LOG2_H_
@@ -18285,7 +18410,8 @@ extern "C" {
#endif
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i);
-bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a);
+void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e,
+ upb_EnumValueDef* v);
const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e);
// Allocate and initialize an array of |n| enum defs.
@@ -18379,6 +18505,151 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a);
#endif /* UPB_REFLECTION_INTERNAL_STRDUP2_H_ */
+#ifndef GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
+#define GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
+
+// IWYU pragma: begin_exports
+
+#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0
+// This header is checked in.
+#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 1
+// This header is generated at build time by the bootstrapping process.
+#else
+// This is the normal header, generated by upb_c_proto_library().
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+
+
+// Must be last.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct pb_enumvalue_JsonEnumValueOptions {
+ upb_Message UPB_PRIVATE(base);
+} pb_enumvalue_JsonEnumValueOptions;
+
+struct google_protobuf_EnumValueOptions;
+
+
+
+/* pb.enumvalue.JsonEnumValueOptions */
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_new(upb_Arena* arena) {
+ return (pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena);
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse(const char* buf, size_t size,
+ upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, NULL, 0,
+ arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse_ex(
+ const char* buf, size_t size, const upb_ExtensionRegistry* extreg,
+ int options, upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, extreg,
+ options, arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize(const pb_enumvalue_JsonEnumValueOptions* msg,
+ upb_Arena* arena, size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, 0, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize_ex(const pb_enumvalue_JsonEnumValueOptions* msg,
+ int options, upb_Arena* arena,
+ size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, options, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_clear_string(pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ upb_Message_ClearBaseField(UPB_UPCAST(msg), &field);
+}
+UPB_INLINE upb_StringView pb_enumvalue_JsonEnumValueOptions_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ upb_StringView default_val = upb_StringView_FromString("");
+ upb_StringView ret;
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field,
+ &default_val, &ret);
+ return ret;
+}
+UPB_INLINE bool pb_enumvalue_JsonEnumValueOptions_has_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ return upb_Message_HasBaseField(UPB_UPCAST(msg), &field);
+}
+
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_set_string(pb_enumvalue_JsonEnumValueOptions* msg, upb_StringView value) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ upb_Message_SetBaseField((upb_Message*)msg, &field, &value);
+}
+
+UPB_INLINE bool pb_enumvalue_has_json(const struct google_protobuf_EnumValueOptions* msg) {
+ return upb_Message_HasExtension((upb_Message*)msg, pb_enumvalue_json_ext);
+}
+
+UPB_INLINE void pb_enumvalue_clear_json(struct google_protobuf_EnumValueOptions* msg) {
+ upb_Message_ClearExtension((upb_Message*)msg, pb_enumvalue_json_ext);
+}
+UPB_INLINE const pb_enumvalue_JsonEnumValueOptions*
+pb_enumvalue_json(const struct google_protobuf_EnumValueOptions* msg) {
+ const upb_MiniTableExtension* ext = pb_enumvalue_json_ext;
+ UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field)));
+ UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(
+ &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
+ const pb_enumvalue_JsonEnumValueOptions* default_val = NULL;
+ const pb_enumvalue_JsonEnumValueOptions* ret;
+ _upb_Message_GetExtensionField((upb_Message*)msg, ext, &default_val, &ret);
+ return ret;
+}
+
+UPB_INLINE void pb_enumvalue_set_json(struct google_protobuf_EnumValueOptions* msg,
+ const pb_enumvalue_JsonEnumValueOptions* val,
+ upb_Arena* arena) {
+ const upb_MiniTableExtension* ext = pb_enumvalue_json_ext;
+ UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field)));
+ UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(
+ &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
+ bool ok = upb_Message_SetExtension((upb_Message*)msg, ext, &val, arena);
+ UPB_ASSERT(ok);
+}
+UPB_INLINE struct pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_mutable_json(
+ struct google_protobuf_EnumValueOptions* msg, upb_Arena* arena) {
+ struct pb_enumvalue_JsonEnumValueOptions* sub = (struct pb_enumvalue_JsonEnumValueOptions*)pb_enumvalue_json(msg);
+ if (sub == NULL) {
+ sub = (struct pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena);
+ if (sub) pb_enumvalue_set_json(msg, sub, arena);
+ }
+ return sub;
+}
+#ifdef __cplusplus
+ } /* extern "C" */
+#endif
+
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ */
+#endif
+
+// IWYU pragma: end_exports
+
+#endif // GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
#ifndef UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_
#define UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_
@@ -19133,6 +19404,7 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) {
#undef UPB_TSAN
#undef UPB_DEPRECATED
#undef UPB_GNUC_MIN
+#undef UPB_CLANG_MIN
#undef UPB_DESCRIPTOR_UPB_H_FILENAME
#undef UPB_DESC_MINITABLE
#undef UPB_IS_GOOGLE3
@@ -19159,3 +19431,6 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) {
#undef UPB_DEPRECATE_AND_INLINE
#undef UPB_MAYBE_ASSUME
#undef UPB_ATTR_CONST
+#undef _UPB_STRINGIFY
+#undef _UPB_STRINGIFY2
+#undef UPB_CONSTRUCTOR
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index a9dc98677a..f86cfc14c0 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -22,7 +22,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
-#define PHP_PROTOBUF_VERSION "5.36.0"
+#define PHP_PROTOBUF_VERSION "5.36.0RC2"
// ptr -> PHP object cache. This is a weak map that caches lazily-created
// wrapper objects around upb types:
diff --git a/pkg/BUILD.bazel b/pkg/BUILD.bazel
index f698c5db5e..2ddb85425f 100644
--- a/pkg/BUILD.bazel
+++ b/pkg/BUILD.bazel
@@ -13,14 +13,9 @@ package_naming(
)
pkg_files(
- name = "wkt_protos_files",
+ name = "release_all_options_protos_files",
srcs = [
- "//:well_known_type_protos",
- "//csharp:c_sharp_features_proto_srcs",
- "//go:go_features_proto_srcs",
- "//java/core:java_features_proto_srcs",
- "//src/google/protobuf:cpp_features_proto_srcs",
- "//src/google/protobuf:descriptor_proto_srcs",
+ "//src/google/protobuf:release_all_options_proto_srcs",
],
prefix = "include/google/protobuf",
visibility = ["//visibility:private"],
@@ -92,7 +87,7 @@ pkg_zip(
":compiler_plugin_protos_files",
":protoc_files",
":protoc_readme",
- ":wkt_protos_files",
+ ":release_all_options_protos_files",
],
package_file_name = "protoc-{version}-{platform}.zip",
package_variables = ":protobuf_pkg_naming",
@@ -118,16 +113,9 @@ gen_file_lists(
":protoc-gen-upbdefs": "protoc-gen-upbdefs",
":protoc-gen-upb_minitable": "protoc-gen-upb_minitable",
# Protos:
- "//src/google/protobuf:well_known_type_protos": "wkt_protos",
- "//src/google/protobuf:cpp_file_options_proto": "cpp_file_options_proto",
- "//src/google/protobuf:cpp_features_proto": "cpp_features_proto",
"//src/google/protobuf:descriptor_proto": "descriptor_proto",
- "//src/google/protobuf:json_enumvalue_options_proto": "json_enumvalue_options_proto",
- "//src/google/protobuf:json_enumvalue_options_cc_proto": "json_enumvalue_options_cc_proto",
"//src/google/protobuf/compiler:plugin_proto": "plugin_proto",
- "//csharp:c_sharp_features_proto": "c_sharp_features_proto",
- "//java/core:java_features_proto": "java_features_proto,src/google/protobuf/compiler/java/",
- "//go:go_features_proto": "go_features_proto,go/",
+ "//src/google/protobuf:release_all_options_proto_srcs": "release_all_options_protos",
# Test libraries:
":common_test": "common_test",
diff --git a/protobuf_version.bzl b/protobuf_version.bzl
index 042bcb7425..4c42b59d76 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 = "36.0"
-PROTOBUF_JAVA_VERSION = "4.36.0"
-PROTOBUF_PYTHON_VERSION = "7.36.0"
-PROTOBUF_PHP_VERSION = "5.36.0"
-PROTOBUF_RUBY_VERSION = "4.36.0"
-PROTOBUF_RUST_VERSION = "4.36.0"
+PROTOC_VERSION = "36.0-rc-2"
+PROTOBUF_JAVA_VERSION = "4.36.0-RC2"
+PROTOBUF_PYTHON_VERSION = "7.36.0rc2"
+PROTOBUF_PHP_VERSION = "5.36.0RC2"
+PROTOBUF_RUBY_VERSION = "4.36.0.rc.2"
+PROTOBUF_RUST_VERSION = "4.36.0-rc.2"
diff --git a/python/descriptor.c b/python/descriptor.c
index 3df441a3a8..251fdd2b6d 100644
--- a/python/descriptor.c
+++ b/python/descriptor.c
@@ -141,6 +141,8 @@ static PyObject* PyUpb_DescriptorBase_GetCached(PyObject** cached,
#if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS
upb_Message_Freeze(opts2, opts2_layout);
+#else
+ PyUpb_Arena_SetFrozen(py_arena, true);
#endif
*cached = PyUpb_Message_Get(opts2, m, py_arena);
Py_DECREF(py_arena);
diff --git a/python/descriptor_containers.c b/python/descriptor_containers.c
index 1bfbc69bf6..fec0797f4e 100644
--- a/python/descriptor_containers.c
+++ b/python/descriptor_containers.c
@@ -39,6 +39,21 @@ typedef enum {
kPyUpb_CompareNotImplemented,
} PyUpb_CompareResult;
+static PyUpb_CompareResult PyUpb_CompareUnrecognized(void) {
+#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED
+ return kPyUpb_CompareNotImplemented;
+#else
+ if (PyErr_WarnEx(
+ PyExc_FutureWarning,
+ "Comparing descriptor containers with unrecognized types will return "
+ "NotImplemented in 2027.",
+ 3) < 0) {
+ return kPyUpb_CompareError;
+ }
+ return kPyUpb_CompareNotEqual;
+#endif
+}
+
// -----------------------------------------------------------------------------
// ByNameIterator
// -----------------------------------------------------------------------------
@@ -234,11 +249,7 @@ static PyUpb_CompareResult PyUpb_GenericSequence_IsEqual(
}
if (!PyList_Check(other)) {
-#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED
- return kPyUpb_CompareNotImplemented;
-#else
- return kPyUpb_CompareNotEqual;
-#endif
+ return PyUpb_CompareUnrecognized();
}
// return list(self) == other
@@ -554,11 +565,7 @@ static PyUpb_CompareResult PyUpb_ByNameMap_IsEqual(PyUpb_ByNameMap* self,
}
if (!PyDict_Check(other)) {
-#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED
- return kPyUpb_CompareNotImplemented;
-#else
- return kPyUpb_CompareNotEqual;
-#endif
+ return PyUpb_CompareUnrecognized();
}
PyObject* self_dict = PyDict_New();
@@ -807,11 +814,7 @@ static PyUpb_CompareResult PyUpb_ByNumberMap_IsEqual(PyUpb_ByNumberMap* self,
}
if (!PyDict_Check(other)) {
-#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED
- return kPyUpb_CompareNotImplemented;
-#else
- return kPyUpb_CompareNotEqual;
-#endif
+ return PyUpb_CompareUnrecognized();
}
PyObject* self_dict = PyDict_New();
diff --git a/python/dist/BUILD.bazel b/python/dist/BUILD.bazel
index 1292d74dff..a87dfc4c85 100644
--- a/python/dist/BUILD.bazel
+++ b/python/dist/BUILD.bazel
@@ -26,21 +26,9 @@ py_dist_module(
)
py_proto_library(
- name = "well_known_proto_py_pb2",
+ name = "language_neutral_protos_py_pb2",
deps = [
- "//:any_proto",
- "//:api_proto",
- "//:descriptor_proto",
- "//:duration_proto",
- "//:empty_proto",
- "//:field_mask_proto",
- "//:json_enumvalue_options_proto",
- "//:json_options_proto",
- "//:source_context_proto",
- "//:struct_proto",
- "//:timestamp_proto",
- "//:type_proto",
- "//:wrappers_proto",
+ "//src/google/protobuf:language_neutral_protos",
],
)
@@ -246,13 +234,17 @@ selects.config_setting_group(
)
pkg_files(
- name = "generated_wkt",
+ name = "generated_bootstrap",
srcs = [
- ":well_known_proto_py_pb2",
+ ":language_neutral_protos_py_pb2",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
"//src/google/protobuf:descriptor_upb_reflection_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_c_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_minitable_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_reflection_proto",
"//upb/reflection:descriptor_upb_proto",
+ "//upb/reflection:json_enumvalue_options_upb_proto",
],
prefix = "google/protobuf",
)
@@ -311,7 +303,7 @@ pkg_tar(
srcs = [
":dist_source_files",
":filegroup_source_files",
- ":generated_wkt",
+ ":generated_bootstrap",
":generated_wkt_compiler",
":utf8_range_source_files",
"//python:python_source_files",
@@ -405,9 +397,9 @@ py_wheel(
}),
version = PROTOBUF_PYTHON_VERSION,
deps = [
+ ":language_neutral_protos_py_pb2",
":message_mod",
":plugin_py_pb2",
- ":well_known_proto_py_pb2",
"//:python_srcs",
],
)
@@ -445,8 +437,8 @@ py_wheel(
}),
version = PROTOBUF_PYTHON_VERSION,
deps = [
+ ":language_neutral_protos_py_pb2",
":plugin_py_pb2",
- ":well_known_proto_py_pb2",
"//:python_srcs",
],
)
diff --git a/python/dist/py_proto_library.bzl b/python/dist/py_proto_library.bzl
index 756ef6d2fb..46b00e6c41 100644
--- a/python/dist/py_proto_library.bzl
+++ b/python/dist/py_proto_library.bzl
@@ -105,7 +105,11 @@ def _py_proto_library_aspect_impl(target, ctx):
[_get_real_short_path(file) for file in proto_sources],
progress_message = "Generating Python protos for :" + ctx.label.name,
)
- outs_depset = depset(srcs)
+ transitive_py_sources = [dep[PyInfo].transitive_sources for dep in ctx.rule.attr.deps if PyInfo in dep] if hasattr(ctx.rule.attr, "deps") else []
+ outs_depset = depset(
+ direct = srcs,
+ transitive = transitive_py_sources,
+ )
return [
PyInfo(transitive_sources = outs_depset),
]
diff --git a/python/extension_dict.c b/python/extension_dict.c
index 4783ed70ae..01e13d5c6a 100644
--- a/python/extension_dict.c
+++ b/python/extension_dict.c
@@ -7,6 +7,7 @@
#include "python/extension_dict.h"
+#include "google/protobuf/breaking_changes.h"
#include "python/message.h"
#include "python/protobuf.h"
#include "upb/reflection/def.h"
@@ -127,8 +128,9 @@ static int PyUpb_ExtensionDict_AssignSubscript(PyObject* _self, PyObject* key,
const upb_FieldDef* f = PyUpb_Message_GetExtensionDef(self->msg, key);
if (!f) return -1;
if (PyUpb_Message_IsFrozen(self->msg)) {
- PyUpb_SetFrozenError();
- return -1;
+ if (!PyUpb_CheckFrozen(true, "Message is immutable.")) {
+ return -1;
+ }
}
if (val) {
return PyUpb_Message_SetFieldValue(self->msg, f, val, PyExc_TypeError);
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index 1223991329..cf9393a255 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__ = '7.36.0'
+__version__ = '7.36.0rc2'
diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py
index 6bf19d8691..6cc81441d5 100755
--- a/python/google/protobuf/descriptor.py
+++ b/python/google/protobuf/descriptor.py
@@ -245,6 +245,12 @@ class DescriptorBase(metaclass=DescriptorMetaclass):
# If either has been reset by gencode, reload options.
if not self._options or not self._loaded_options:
self._LazyLoadOptions()
+ if (
+ self._options
+ and hasattr(self._options, '_SetFrozen')
+ and not getattr(self._options, '_frozen', False)
+ ):
+ self._options._SetFrozen()
return self._options
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index ba4b7a1299..896faee3ab 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -19,6 +19,7 @@ are:
import collections.abc
import copy
import pickle
+import warnings
from typing import (
Any,
Iterable,
@@ -42,6 +43,16 @@ from google.protobuf.descriptor import FieldDescriptor
from google.protobuf import message
+def _CheckFrozen(is_frozen: bool, msg: str) -> None:
+ if is_frozen:
+ warnings.warn(
+ 'Mutating messages or containers returned by GetOptions() is'
+ ' deprecated and will raise an exception in a future release.',
+ category=FutureWarning,
+ stacklevel=3,
+ )
+
+
class BaseContainer(Sequence[_T]):
"""Base container class."""
@@ -89,8 +100,7 @@ class BaseContainer(Sequence[_T]):
self._frozen = True
def _AssureWritable(self) -> 'BaseContainer[_T]':
- if self._frozen:
- raise message.FrozenInstanceError('Container is immutable')
+ _CheckFrozen(self._frozen, 'Container is immutable')
return self
def sort(self, *args, **kwargs) -> None:
@@ -447,8 +457,7 @@ class ScalarMap(MutableMapping[_K, _V]):
self._frozen = True
def _AssureWritable(self) -> 'ScalarMap[_K, _V]':
- if self._frozen:
- raise message.FrozenInstanceError('Map is immutable')
+ _CheckFrozen(self._frozen, 'Map is immutable')
return self
def __getitem__(self, key: _K) -> _V:
@@ -582,8 +591,7 @@ class MessageMap(MutableMapping[_K, _V]):
val._SetFrozen()
def _AssureWritable(self) -> 'MessageMap[_K, _V]':
- if self._frozen:
- raise message.FrozenInstanceError('Map is immutable')
+ _CheckFrozen(self._frozen, 'Map is immutable')
return self
def __getitem__(self, key: _K) -> _V:
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index 25f9d970ea..53bd94f9ea 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -1606,7 +1606,12 @@ def _SetFrozen(self):
def _AssureWritable(self):
if self._frozen:
- raise message_mod.FrozenInstanceError('Message is immutable')
+ warnings.warn(
+ 'Mutating messages or containers returned by GetOptions() is'
+ ' deprecated and will raise an exception in a future release.',
+ category=FutureWarning,
+ stacklevel=3,
+ )
return self
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 2f3bc7c799..3d0125d08b 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -313,9 +313,7 @@ static PyObject* GetOrBuildMessageInDefaultPool(
}
}
-#if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS
cmsg->state = MESSAGE_FROZEN;
-#endif
// Cache the result.
{
diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc
index 8e7b7d662c..d1eb1129dc 100644
--- a/python/google/protobuf/pyext/descriptor_containers.cc
+++ b/python/google/protobuf/pyext/descriptor_containers.cc
@@ -307,6 +307,21 @@ enum class CompareResult {
kNotImplemented,
};
+static CompareResult CompareUnrecognized() {
+#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED
+ return CompareResult::kNotImplemented;
+#else
+ if (PyErr_WarnEx(
+ PyExc_FutureWarning,
+ "Comparing descriptor containers with unrecognized types will return "
+ "NotImplemented in 2027.",
+ 3) < 0) {
+ return CompareResult::kError;
+ }
+ return CompareResult::kNotEqual;
+#endif
+}
+
// A sequence container can only be equal to another sequence container, or (for
// backward compatibility) to a list containing the same items.
static CompareResult DescriptorSequence_Equal(PyContainer* self,
@@ -347,13 +362,7 @@ static CompareResult DescriptorSequence_Equal(PyContainer* self,
return CompareResult::kEqual;
}
-#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED
- // Any other object is not implemented.
- return CompareResult::kNotImplemented;
-#else
- // Any other object is different.
- return CompareResult::kNotEqual;
-#endif
+ return CompareUnrecognized();
}
// A mapping container can only be equal to another mapping container, or (for
@@ -401,13 +410,7 @@ static CompareResult DescriptorMapping_Equal(PyContainer* self,
return CompareResult::kEqual;
}
-#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED
- // Any other object is not implemented.
- return CompareResult::kNotImplemented;
-#else
- // Any other object is different.
- return CompareResult::kNotEqual;
-#endif
+ return CompareUnrecognized();
}
static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) {
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 61ea2c0a39..c998256424 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -29,6 +29,7 @@
#include "absl/log/absl_check.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
+#include "google/protobuf/breaking_changes.h"
#include "google/protobuf/pyext/lazy_unique_ptr.h"
#ifndef PyVarObject_HEAD_INIT
@@ -494,6 +495,26 @@ PyObject* SetMessageFrozenError() {
return SetFrozenError("Message is immutable.");
}
+int WarnMessageFrozen() {
+ return PyErr_WarnEx(
+ PyExc_FutureWarning,
+ "Mutating messages or containers returned by GetOptions() is deprecated"
+ " and will raise an exception in a future release.",
+ 3);
+}
+
+int CheckFrozen(CMessage* parent, const char* error_msg) {
+ if (parent->state == MESSAGE_FROZEN) {
+#if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS
+ SetFrozenError(error_msg);
+ return -1;
+#else
+ return WarnMessageFrozen();
+#endif
+ }
+ return 0;
+}
+
// Format an error message for unexpected types.
// Always return with an exception set.
void FormatTypeError(PyObject* arg, const char* expected_types) {
@@ -834,8 +855,10 @@ Message* AssureWritable(CMessage* self) {
case MESSAGE_MUTABLE:
return const_cast(self->message);
case MESSAGE_FROZEN:
- SetMessageFrozenError();
- return nullptr;
+ if (CheckFrozen(self, "Message is immutable.") < 0) {
+ return nullptr;
+ }
+ return const_cast(self->message);
case MESSAGE_MUTABLE_DEFAULT:
break;
}
@@ -1025,8 +1048,7 @@ int DeleteRepeatedField(CMessage* self, const FieldDescriptor* field_descriptor,
int CheckRepeatedFieldDeletion(CMessage* parent,
const FieldDescriptor* field_descriptor,
PyObject* slice) {
- if (parent->state == python::MESSAGE_FROZEN) {
- SetMessageFrozenError();
+ if (CheckFrozen(parent, "Message is immutable.") < 0) {
return -1;
}
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
index 4653fd3706..bc993e2c17 100644
--- a/python/google/protobuf/pyext/message.h
+++ b/python/google/protobuf/pyext/message.h
@@ -360,6 +360,12 @@ PyObject* SetFrozenError(const char* msg);
// Sets a Python FrozenInstanceError with the default error message for messages
// type and returns nullptr.
PyObject* SetMessageFrozenError();
+// Emits a DeprecationWarning when mutating a frozen message or container in
+// OSS.
+int WarnMessageFrozen();
+// Returns 0 if writable (might have thrown warning).
+// Returns -1 on error (sets Python exception).
+int CheckFrozen(CMessage* parent, const char* error_msg);
PyObject* PyMessage_New(const Descriptor* descriptor,
PyObject* py_message_factory);
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index aef12e0037..044016cff6 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -16,6 +16,7 @@
#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/message.h"
#include "google/protobuf/reflection.h"
+#include "google/protobuf/breaking_changes.h"
#include "google/protobuf/pyext/descriptor.h"
#include "google/protobuf/pyext/descriptor_pool.h"
#include "google/protobuf/pyext/message.h"
@@ -28,9 +29,6 @@ namespace python {
namespace repeated_composite_container {
-static PyObject* SetContainerFrozenError() {
- return SetFrozenError("Container is immutable");
-}
// ---------------------------------------------------------------------
// len()
@@ -285,8 +283,8 @@ static PyObject* Remove(PyObject* pself, PyObject* value) {
RepeatedCompositeContainer* self =
reinterpret_cast(pself);
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
Py_ssize_t len = Length(reinterpret_cast(self));
@@ -406,8 +404,8 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) {
RepeatedCompositeContainer* self =
reinterpret_cast(pself);
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
// Support the old sort_function argument for backwards
@@ -455,8 +453,8 @@ static PyObject* Reverse(PyObject* pself) {
RepeatedCompositeContainer* self =
reinterpret_cast(pself);
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
// TODO: b/517235198 - Reify even for empty sequences.
@@ -499,8 +497,8 @@ static PyObject* Pop(PyObject* pself, PyObject* args) {
RepeatedCompositeContainer* self =
reinterpret_cast(pself);
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
Py_ssize_t index = -1;
@@ -602,7 +600,7 @@ PyTypeObject RepeatedCompositeContainer_Type = {
#if PY_VERSION_HEX >= 0x03080000
0, // tp_vectorcall_offset
#else
- nullptr, // tp_print
+ nullptr, // tp_print
#endif
nullptr, // tp_getattr
nullptr, // tp_setattr
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc
index a44e15d3b0..c149bf8703 100644
--- a/python/google/protobuf/pyext/repeated_scalar_container.cc
+++ b/python/google/protobuf/pyext/repeated_scalar_container.cc
@@ -26,6 +26,7 @@
#include "google/protobuf/descriptor.h"
#include "google/protobuf/message.h"
#include "google/protobuf/reflection.h"
+#include "google/protobuf/breaking_changes.h"
#include "google/protobuf/pyext/message.h"
#include "google/protobuf/pyext/safe_numerics.h"
#include "google/protobuf/pyext/scoped_pyobject_ptr.h"
@@ -526,9 +527,6 @@ bool CallWithSpan(const Message* message,
namespace repeated_scalar_container {
-static PyObject* SetContainerFrozenError() {
- return SetFrozenError("Container is immutable");
-}
static int InternalAssignRepeatedField(RepeatedScalarContainer* self,
PyObject* list) {
@@ -1057,8 +1055,8 @@ static PyObject* Remove(PyObject* pself, PyObject* value) {
// Even if the value doesn't exist in the container, raise immutability error
// prior to value error if applicable.
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
Py_ssize_t match_index = -1;
@@ -1306,8 +1304,8 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) {
RepeatedScalarContainer* self =
reinterpret_cast(pself);
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
// Support the old sort_function argument for backwards
@@ -1353,8 +1351,8 @@ static PyObject* Reverse(PyObject* pself) {
RepeatedScalarContainer* self =
reinterpret_cast(pself);
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
// TODO: b/517235198 - Reify even for empty sequences.
@@ -1405,8 +1403,8 @@ static PyObject* Pop(PyObject* pself, PyObject* args) {
// Even if the value doesn't exist in the container, raise immutability error
// prior to value error.
- if (self->parent->state == python::MESSAGE_FROZEN) {
- return SetContainerFrozenError();
+ if (CheckFrozen(self->parent, "Container is immutable") < 0) {
+ return nullptr;
}
Py_ssize_t index = -1;
diff --git a/python/google/protobuf/runtime_version.py b/python/google/protobuf/runtime_version.py
index 45950bff17..9fbfcb6169 100644
--- a/python/google/protobuf/runtime_version.py
+++ b/python/google/protobuf/runtime_version.py
@@ -30,7 +30,7 @@ OSS_DOMAIN = Domain.PUBLIC
OSS_MAJOR = 7
OSS_MINOR = 36
OSS_PATCH = 0
-OSS_SUFFIX = '-dev'
+OSS_SUFFIX = '-rc2'
DOMAIN = OSS_DOMAIN
MAJOR = OSS_MAJOR
diff --git a/python/map.c b/python/map.c
index 98ea09366a..6217e06a3b 100644
--- a/python/map.c
+++ b/python/map.c
@@ -7,6 +7,7 @@
#include "python/map.h"
+#include "google/protobuf/breaking_changes.h"
#include "python/convert.h"
#include "python/message.h"
#include "python/protobuf.h"
@@ -130,14 +131,16 @@ bool PyUpb_MapContainer_IsFrozen(PyUpb_MapContainer* self) {
if (PyUpb_MapContainer_IsStub(self)) {
return PyUpb_Message_IsFrozen(self->ptr.parent);
} else {
- return upb_Map_IsFrozen(self->ptr.map);
+ return upb_Map_IsFrozen(self->ptr.map) || PyUpb_Arena_IsFrozen(self->arena);
}
}
upb_Map* PyUpb_MapContainer_AssureWritable(PyObject* _self) {
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
if (PyUpb_MapContainer_IsFrozen(self)) {
- return (upb_Map*)PyUpb_SetFrozenErrorWithMsg("Map is immutable");
+ if (!PyUpb_CheckFrozen(true, "Map is immutable")) {
+ return NULL;
+ }
}
self->version++;
diff --git a/python/message.c b/python/message.c
index 4db8c0157e..e559c08ebb 100644
--- a/python/message.c
+++ b/python/message.c
@@ -13,6 +13,7 @@
#include
#include
+#include "google/protobuf/breaking_changes.h"
#include "python/convert.h"
#include "python/descriptor.h"
#include "python/extension_dict.h"
@@ -673,8 +674,9 @@ static void PyUpb_Message_SetField(PyUpb_Message* parent, const upb_FieldDef* f,
*/
bool PyUpb_Message_AssureWritable(PyUpb_Message* self) {
if (PyUpb_Message_IsFrozen((PyObject*)self)) {
- PyUpb_SetFrozenError();
- return false;
+ if (!PyUpb_CheckFrozen(true, "Message is immutable.")) {
+ return false;
+ }
}
if (!PyUpb_Message_IsStub(self)) return true;
@@ -1061,7 +1063,8 @@ bool PyUpb_Message_IsFrozen(PyObject* _self) {
while (PyUpb_Message_IsStub(self)) {
self = self->ptr.parent;
}
- bool is_frozen = upb_Message_IsFrozen(self->ptr.msg);
+ bool is_frozen =
+ upb_Message_IsFrozen(self->ptr.msg) || PyUpb_Arena_IsFrozen(self->arena);
// Invariant: Since we only store the parent *message* (and not any parent
// repeated field or map) in a stub's `ptr.parent`, we wouldn't correctly
// handle the case where a parent message is unfrozen but a containing
diff --git a/python/protobuf.c b/python/protobuf.c
index 5be18043df..6a72273015 100644
--- a/python/protobuf.c
+++ b/python/protobuf.c
@@ -12,6 +12,7 @@
#include
#include
+#include "google/protobuf/breaking_changes.h"
#include "python/descriptor.h"
#include "python/descriptor_containers.h"
#include "python/descriptor_pool.h"
@@ -342,6 +343,7 @@ typedef struct {
PyObject_HEAD
upb_Arena* arena;
// clang-format on
+ bool frozen;
} PyUpb_Arena;
#ifdef __GLIBC__
@@ -386,6 +388,7 @@ PyObject* PyUpb_Arena_New(void) {
PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
PyUpb_Arena* arena = (void*)PyType_GenericAlloc(state->arena_type, 0);
arena->arena = PyUpb_NewArena();
+ arena->frozen = false;
return &arena->ob_base;
}
@@ -398,6 +401,14 @@ upb_Arena* PyUpb_Arena_Get(PyObject* arena) {
return ((PyUpb_Arena*)arena)->arena;
}
+bool PyUpb_Arena_IsFrozen(PyObject* arena) {
+ return ((PyUpb_Arena*)arena)->frozen;
+}
+
+void PyUpb_Arena_SetFrozen(PyObject* arena, bool frozen) {
+ ((PyUpb_Arena*)arena)->frozen = frozen;
+}
+
static PyType_Slot PyUpb_Arena_Slots[] = {
{Py_tp_dealloc, PyUpb_Arena_Dealloc},
{0, NULL},
@@ -546,6 +557,26 @@ PyObject* PyUpb_SetFrozenError(void) {
return PyUpb_SetFrozenErrorWithMsg("Message is immutable.");
}
+int PyUpb_WarnFrozen(void) {
+ return PyErr_WarnEx(
+ PyExc_FutureWarning,
+ "Mutating messages or containers returned by GetOptions() is deprecated"
+ " and will raise an exception in a future release.",
+ 3);
+}
+
+bool PyUpb_CheckFrozen(bool is_frozen, const char* error_msg) {
+ if (is_frozen) {
+#if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS
+ PyUpb_SetFrozenErrorWithMsg(error_msg);
+ return false;
+#else
+ return PyUpb_WarnFrozen() >= 0;
+#endif
+ }
+ return true;
+}
+
// -----------------------------------------------------------------------------
// Module Entry Point
// -----------------------------------------------------------------------------
diff --git a/python/protobuf.h b/python/protobuf.h
index cd14039fe4..240c7d6f11 100644
--- a/python/protobuf.h
+++ b/python/protobuf.h
@@ -173,6 +173,8 @@ PyUpb_WeakMap* PyUpb_ObjCache_Instance(void);
PyObject* PyUpb_Arena_New(void);
upb_Arena* PyUpb_Arena_Get(PyObject* arena);
+bool PyUpb_Arena_IsFrozen(PyObject* arena);
+void PyUpb_Arena_SetFrozen(PyObject* arena, bool frozen);
// -----------------------------------------------------------------------------
// Utilities
@@ -234,5 +236,9 @@ PyObject* PyUpb_SetFrozenError(void);
// Sets a Python FrozenInstanceError with the given custom message and returns
// NULL.
PyObject* PyUpb_SetFrozenErrorWithMsg(const char* msg);
+// Emits a DeprecationWarning when mutating a frozen message or container in
+// OSS.
+int PyUpb_WarnFrozen(void);
+bool PyUpb_CheckFrozen(bool is_frozen, const char* error_msg);
#endif // PYUPB_PROTOBUF_H__
diff --git a/python/repeated.c b/python/repeated.c
index 5608e5bda4..30dc3e0679 100644
--- a/python/repeated.c
+++ b/python/repeated.c
@@ -108,14 +108,17 @@ bool PyUpb_RepeatedContainer_IsFrozen(PyUpb_RepeatedContainer* self) {
if (PyUpb_RepeatedContainer_IsStub(self)) {
return PyUpb_Message_IsFrozen(self->ptr.parent);
} else {
- return upb_Array_IsFrozen(self->ptr.arr);
+ return upb_Array_IsFrozen(self->ptr.arr) ||
+ PyUpb_Arena_IsFrozen(self->arena);
}
}
upb_Array* PyUpb_RepeatedContainer_AssureWritable(PyObject* _self) {
PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
if (PyUpb_RepeatedContainer_IsFrozen(self)) {
- return (upb_Array*)PyUpb_SetFrozenErrorWithMsg("Container is immutable");
+ if (!PyUpb_CheckFrozen(true, "Container is immutable")) {
+ return NULL;
+ }
}
upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
@@ -967,7 +970,9 @@ static PyObject* PyUpb_RepeatedContainer_Sort(PyObject* pself, PyObject* args,
}
if (PyUpb_RepeatedContainer_IsFrozen((PyUpb_RepeatedContainer*)pself)) {
- return PyUpb_SetFrozenErrorWithMsg("Container is immutable");
+ if (!PyUpb_CheckFrozen(true, "Container is immutable")) {
+ return NULL;
+ }
}
// TODO:b/517235198 - Reify even for empty sequences.
diff --git a/regenerate_stale_files.sh b/regenerate_stale_files.sh
index 4c6f981576..0aa7d3d931 100755
--- a/regenerate_stale_files.sh
+++ b/regenerate_stale_files.sh
@@ -24,6 +24,7 @@ STALENESS_TESTS=(
"php:proto_staleness_test"
"ruby/ext/google/protobuf_c:test_amalgamation_staleness"
"upb/reflection:descriptor_upb_proto_staleness_test"
+ "upb/reflection:json_enumvalue_options_upb_proto_staleness_test"
"upb_generator:plugin_upb_proto_staleness_test"
)
diff --git a/ruby/BUILD.bazel b/ruby/BUILD.bazel
index 8e1c85343c..8d2d1ab506 100755
--- a/ruby/BUILD.bazel
+++ b/ruby/BUILD.bazel
@@ -93,8 +93,8 @@ selects.config_setting_group(
internal_copy_files(
name = "copied_wkt_proto_files",
srcs = [
- "//:well_known_type_protos",
"//src/google/protobuf:descriptor_proto_srcs",
+ "//src/google/protobuf:language_neutral_proto_srcs",
"//src/google/protobuf/compiler:plugin.proto",
],
strip_prefix = "src",
diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c
index 33ee082ab1..22eed466ae 100644
--- a/ruby/ext/google/protobuf_c/ruby-upb.c
+++ b/ruby/ext/google/protobuf_c/ruby-upb.c
@@ -38,6 +38,13 @@
#define UPB_GNUC_MIN(x, y) 0
#endif
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define UPB_CLANG_MIN(x, y) \
+ (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
+#else
+#define UPB_CLANG_MIN(x, y) 0
+#endif
+
// Macros for checking for compiler attributes, defined here to avoid the
// problem described in
// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html.
@@ -602,10 +609,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name; \
- extern type __stop_linkarr_##name; \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name; \
+ extern type __stop_linkarr_##name; \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -616,13 +625,15 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name __asm( \
- "section$start$__DATA$__la_" #name); \
- extern type __stop_linkarr_##name __asm( \
- "section$end$__DATA$" \
- "__la_" #name); \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name __asm( \
+ "section$start$__DATA$__la_" #name); \
+ extern type __stop_linkarr_##name __asm( \
+ "section$end$__DATA$" \
+ "__la_" #name); \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -660,7 +671,9 @@ Error, UINTPTR_MAX is undefined
// Linker arrays are not supported on this platform. Make macros no-ops.
#define UPB_LINKARR_APPEND(name)
-#define UPB_LINKARR_DECLARE(name, type)
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)")
#define UPB_LINKARR_START(name) (NULL)
#define UPB_LINKARR_STOP(name) (NULL)
@@ -677,11 +690,46 @@ Error, UINTPTR_MAX is undefined
#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name)
#endif
-#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define _UPB_STRINGIFY2(x) #x
+#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x)
+
+#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1))
+/*
+ * Workaround for b/456308964 and b/456317163. Although weak constructors
+ * resolve to a single function body, Clang still emits a pointer into
+ * .init_array for every translation unit, causing the constructor to be
+ * executed multiple times and inflating binary size. We wrap the .init_array
+ * entry in a COMDAT group (using inline assembly) to force the linker to
+ * deduplicate the pointer to exactly one instance. %cc is used in preference to
+ * the more widely available %c because %c may under some circumstances still
+ * output a function name including relocation information, which will then
+ * confuse the linker. This was only a problem on gcc; when %cc was introduced
+ * to clang it was just an alias to %c, and clang's %c had already done the
+ * checks that %cc introduced to gcc.
+ * References:
+ * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa
+ * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305
+ */
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
+ __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \
+ void) { \
+ __asm__ volatile( \
+ ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \
+ ".dc.a %cc0\n" \
+ ".popsection\n" \
+ : \
+ : "X"(UPB_PRIVATE(name))); \
+ __VA_ARGS__ \
+ }
+#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \
+ defined(__MINGW32__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
_UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
__attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \
- name)(void)
+ name)(void) { \
+ __VA_ARGS__ \
+ }
#elif defined(_MSC_VER)
/*
* See: https://stackoverflow.com/questions/1113409
@@ -692,17 +740,22 @@ Error, UINTPTR_MAX is undefined
* create a dummy exported weak symbol that prevent this stripping.
*/
#pragma section(".CRT$XCT", read)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
static void __cdecl UPB_PRIVATE(name)(void); \
__declspec(allocate(".CRT$XCT"), selectany) void( \
__cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \
__declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \
&UPB_PRIVATE(name##_); \
- static void __cdecl UPB_PRIVATE(name)(void)
-
+ static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ }
#else
// No constructor support, nothing we can do except not break builds.
-#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void)
+#if defined(__GNUC__) || defined(__clang__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#else
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#endif
#endif
//
@@ -740,9 +793,9 @@ Error, UINTPTR_MAX is undefined
#elif defined(__ELF__) || defined(__wasm__)
-// On ELF, weak aliases work properly, so we can have all weak MiniTables point
-// to the same empty singleton MiniTable. This reduces code size if many
-// MiniTables are tree shaken.
+ // On ELF, weak aliases work properly, so we can have all weak MiniTables
+ // point to the same empty singleton MiniTable. This reduces code size if many
+ // MiniTables are tree shaken.
#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \
__attribute__((weak)) \
const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \
@@ -2389,7 +2442,7 @@ const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init = {
},
};
-static const upb_MiniTable *messages_layout[35] = {
+static const upb_MiniTable *messages_layout_google_protobuf_descriptor_proto_upb_file_layout[35] = {
&google__protobuf__FileDescriptorSet_msg_init,
&google__protobuf__FileDescriptorProto_msg_init,
&google__protobuf__DescriptorProto_msg_init,
@@ -2427,7 +2480,7 @@ static const upb_MiniTable *messages_layout[35] = {
&google__protobuf__GeneratedCodeInfo__Annotation_msg_init,
};
-static const upb_MiniTableEnum *enums_layout[21] = {
+static const upb_MiniTableEnum *enums_layout_google_protobuf_descriptor_proto_upb_file_layout[21] = {
&google__protobuf__Edition_enum_init,
&google__protobuf__ExtensionRangeOptions__VerificationState_enum_init,
&google__protobuf__FeatureSet__EnforceNamingStyle_enum_init,
@@ -2452,8 +2505,8 @@ static const upb_MiniTableEnum *enums_layout[21] = {
};
const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = {
- messages_layout,
- enums_layout,
+ messages_layout_google_protobuf_descriptor_proto_upb_file_layout,
+ enums_layout_google_protobuf_descriptor_proto_upb_file_layout,
NULL,
35,
21,
@@ -2462,6 +2515,81 @@ const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = {
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#include
+
+// Must be last.
+
+extern const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* UPB_PRIVATE(upb_generated_extension_list);
+typedef struct {
+ upb_MiniTableField fields[1];
+} pb__enumvalue__JsonEnumValueOptions_msg_init_Fields;
+
+static const pb__enumvalue__JsonEnumValueOptions_msg_init_Fields pb_enumvalue_JsonEnumValueOptions__fields = {{
+ {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
+}};
+
+const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init = {
+ &pb_enumvalue_JsonEnumValueOptions__fields.fields[0],
+ UPB_SIZE(24, 32), 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(8), 0,
+#ifdef UPB_TRACING_ENABLED
+ "pb.enumvalue.JsonEnumValueOptions",
+#endif
+ UPB_FASTTABLE_INIT({
+ {0x0000000000000000, &_upb_FastDecoder_DecodeUnknown},
+ {0x001000000000000a, &upb_DecodeFast_String_Scalar_Tag1Byte},
+ })
+};
+
+static const upb_MiniTableExtension pb_enumvalue_json_ext_obj = {
+ {998, 0, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsExtension | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
+ {.UPB_PRIVATE(submsg) = &pb__enumvalue__JsonEnumValueOptions_msg_init},
+ &google__protobuf__EnumValueOptions_msg_init,
+
+};
+UPB_LINKARR_APPEND(upb_AllExts)
+const upb_MiniTableExtension* pb_enumvalue_json_ext = &pb_enumvalue_json_ext_obj;
+ static const upb_MiniTable *messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = {
+ &pb__enumvalue__JsonEnumValueOptions_msg_init,
+};
+
+
+static const upb_MiniTableExtension *extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = {
+ &pb_enumvalue_json_ext_obj,
+};
+
+UPB_LINKARR_DECLARE(upb_AllExts, const upb_MiniTableExtension*);
+UPB_CONSTRUCTOR(upb_GeneratedRegistry_Constructor, google_protobuf_json_enumvalue_options_proto_ext_constructor, {
+ static bool finished = false;
+ if (finished) return;
+ finished = true;
+ static UPB_PRIVATE(upb_GeneratedExtensionListEntry) entry = {
+ UPB_LINKARR_START(upb_AllExts),
+ UPB_LINKARR_STOP(upb_AllExts),
+ NULL
+ };
+ UPB_ASSERT(entry.next == NULL);
+ entry.next = UPB_PRIVATE(upb_generated_extension_list);
+ UPB_PRIVATE(upb_generated_extension_list) = &entry;
+})
+const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout = {
+ messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout,
+ NULL,
+ extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout,
+ 1,
+ 0,
+ 1,
+};
+
+
+
#include
#include
@@ -4208,7 +4336,7 @@ static upb_JsonMessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) {
upb_StringView str = jsondec_string(d);
const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f);
const upb_EnumValueDef* ev =
- upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size);
+ upb_EnumDef_FindByJsonNameWithSize(e, str.data, str.size);
upb_JsonMessageValue val = {.ignore = false};
if (ev) {
val.value.int32_val = upb_EnumValueDef_Number(ev);
@@ -4986,11 +5114,12 @@ int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size,
}
-#include
#include
#include
#include
+#include
#include
+#include
#include
@@ -5017,6 +5146,7 @@ static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg,
const upb_MessageDef* m, bool first);
static void jsonenc_value(jsonenc* e, const upb_Message* msg,
const upb_MessageDef* m);
+static void jsonenc_string(jsonenc* e, upb_StringView str);
UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) {
upb_Status_SetErrorMessage(e->status, msg);
@@ -5178,7 +5308,8 @@ static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) {
: upb_EnumDef_FindValueByNumber(e_def, val);
if (ev) {
- jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev));
+ const char* name = upb_EnumValueDef_JsonName(ev);
+ jsonenc_string(e, upb_StringView_FromString(name));
} else {
jsonenc_printf(e, "%" PRId32, val);
}
@@ -11515,6 +11646,28 @@ struct upb_EnumDef {
bool is_sorted; // Whether all of the values are defined in ascending order.
};
+// We store both regular proto enum names and custom JSON enum names in the
+// same strtable (ntoi). This is safe because protoc enforces that custom JSON
+// enum names never conflict with default enum names across different enum
+// values (or are identical, in which case we leave the entry untagged). Because
+// upb_EnumValueDef pointers are arena-aligned to at least 4 bytes (bit 0 is
+// always 0 for untagged pointers), we set bit 0 to tag custom JSON-only names
+// so that regular name lookups can ignore them.
+static const uintptr_t kUpb_EnumDef_JsonOnlyTag = 1ULL;
+
+static upb_value _upb_EnumDef_TagJsonOnly(upb_value v) {
+ v.val |= kUpb_EnumDef_JsonOnlyTag;
+ return v;
+}
+
+static bool _upb_EnumDef_IsJsonOnly(upb_value v) {
+ return (v.val & kUpb_EnumDef_JsonOnlyTag) != 0;
+}
+
+static const upb_EnumValueDef* _upb_EnumDef_Untag(upb_value v) {
+ return (const upb_EnumValueDef*)(v.val & ~kUpb_EnumDef_JsonOnlyTag);
+}
+
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) {
return (upb_EnumDef*)&e[i];
}
@@ -11523,18 +11676,43 @@ const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) {
return e->layout;
}
-bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) {
+void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e,
+ upb_EnumValueDef* v) {
const char* name = upb_EnumValueDef_Name(v);
const upb_value val = upb_value_constptr(v);
- bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a);
- if (!ok) return false;
+ bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, ctx->arena);
+ if (!ok) _upb_DefBuilder_OomErr(ctx);
- // Multiple enumerators can have the same number, first one wins.
+ // Aliased enum values can share the same custom JSON name, first one wins.
+ const char* json_name = upb_EnumValueDef_JsonName(v);
+ size_t json_len = strlen(json_name);
+ if (strcmp(json_name, name) != 0) {
+ upb_value existing_value;
+ if (upb_strtable_lookup2(&e->ntoi, json_name, json_len, &existing_value)) {
+ const upb_EnumValueDef* enumval = _upb_EnumDef_Untag(existing_value);
+ if (upb_EnumValueDef_Number(enumval) != upb_EnumValueDef_Number(v)) {
+ // If the custom JSON name exists, but points to a value with a
+ // different number, then this is a parse/conflict error.
+ _upb_DefBuilder_Errf(ctx,
+ "duplicate custom json_name (%s) in enum (%s)",
+ json_name, upb_EnumDef_FullName(e));
+ }
+ } else {
+ upb_value json_val = _upb_EnumDef_TagJsonOnly(val);
+ if (!upb_strtable_insert(&e->ntoi, json_name, json_len, json_val,
+ ctx->arena)) {
+ _upb_DefBuilder_OomErr(ctx);
+ }
+ }
+ }
+
+ // Multiple enum values can have the same number, first one wins.
const int number = upb_EnumValueDef_Number(v);
if (!upb_inttable_lookup(&e->iton, number, NULL)) {
- return upb_inttable_insert(&e->iton, number, val, a);
+ if (!upb_inttable_insert(&e->iton, number, val, ctx->arena)) {
+ _upb_DefBuilder_OomErr(ctx);
+ }
}
- return true;
}
const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) {
@@ -11591,6 +11769,16 @@ upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) {
int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; }
+const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(const upb_EnumDef* e,
+ const char* name,
+ size_t size) {
+ upb_value v;
+ if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) {
+ return NULL;
+ }
+ return _upb_EnumDef_Untag(v);
+}
+
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const char* name) {
return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name));
@@ -11599,9 +11787,13 @@ const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
const upb_EnumDef* e, const char* name, size_t size) {
upb_value v;
- return upb_strtable_lookup2(&e->ntoi, name, size, &v)
- ? upb_value_getconstptr(v)
- : NULL;
+ if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) {
+ return NULL;
+ }
+ if (_upb_EnumDef_IsJsonOnly(v)) {
+ return NULL;
+ }
+ return upb_value_getconstptr(v);
}
const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e,
@@ -11742,7 +11934,7 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix,
upb_EnumDef_FullName(e));
}
- bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena);
+ bool ok = upb_strtable_init(&e->ntoi, n_value * 2, ctx->arena);
if (!ok) _upb_DefBuilder_OomErr(ctx);
ok = upb_inttable_init(&e->iton, ctx->arena);
@@ -11859,6 +12051,7 @@ struct upb_EnumValueDef {
const google_protobuf_FeatureSet* resolved_features;
const upb_EnumDef* parent;
const char* full_name;
+ const char* json_name;
int32_t number;
};
@@ -11880,7 +12073,7 @@ const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v,
(upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*));
if (!out) return NULL;
- for (int i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
out[i] = (upb_EnumValueDef*)&v[i];
}
qsort(out, n, sizeof(void*), _upb_EnumValueDef_Compare);
@@ -11910,6 +12103,10 @@ const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) {
return v->full_name;
}
+const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v) {
+ return v->json_name ? v->json_name : upb_EnumValueDef_Name(v);
+}
+
const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) {
return _upb_DefBuilder_FullToShort(v->full_name);
}
@@ -11921,6 +12118,19 @@ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) {
return v - upb_EnumDef_Value(v->parent, 0);
}
+static const char* _upb_EnumValueDef_ExtractJsonName(
+ upb_DefBuilder* ctx, const upb_EnumValueDef* v) {
+ if (!upb_EnumValueDef_HasOptions(v)) return NULL;
+ const google_protobuf_EnumValueOptions* opts = (const google_protobuf_EnumValueOptions*)v->opts;
+ if (!pb_enumvalue_has_json(opts)) return NULL;
+ const pb_enumvalue_JsonEnumValueOptions* json_opts = pb_enumvalue_json(opts);
+ if (!json_opts || !pb_enumvalue_JsonEnumValueOptions_has_string(json_opts)) {
+ return NULL;
+ }
+ upb_StringView str = pb_enumvalue_JsonEnumValueOptions_string(json_opts);
+ return upb_strdup2(str.data, str.size, ctx->arena);
+}
+
static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_EnumValueDescriptorProto* val_proto,
const google_protobuf_FeatureSet* parent_features,
@@ -11935,11 +12145,11 @@ static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix,
v->parent = e; // Must happen prior to _upb_DefBuilder_Add()
v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto);
+ v->json_name = _upb_EnumValueDef_ExtractJsonName(ctx, v);
_upb_DefBuilder_Add(ctx, v->full_name,
_upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL));
- bool ok = _upb_EnumDef_Insert(e, v, ctx->arena);
- if (!ok) _upb_DefBuilder_OomErr(ctx);
+ _upb_EnumDef_Insert(ctx, e, v);
}
// Allocate and initialize an array of |n| enum value defs owned by |e|.
@@ -18602,6 +18812,7 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
#undef UPB_TSAN
#undef UPB_DEPRECATED
#undef UPB_GNUC_MIN
+#undef UPB_CLANG_MIN
#undef UPB_DESCRIPTOR_UPB_H_FILENAME
#undef UPB_DESC_MINITABLE
#undef UPB_IS_GOOGLE3
@@ -18628,3 +18839,6 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
#undef UPB_DEPRECATE_AND_INLINE
#undef UPB_MAYBE_ASSUME
#undef UPB_ATTR_CONST
+#undef _UPB_STRINGIFY
+#undef _UPB_STRINGIFY2
+#undef UPB_CONSTRUCTOR
diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h
index 92128cdccc..71dfff57d6 100755
--- a/ruby/ext/google/protobuf_c/ruby-upb.h
+++ b/ruby/ext/google/protobuf_c/ruby-upb.h
@@ -37,6 +37,13 @@
#define UPB_GNUC_MIN(x, y) 0
#endif
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define UPB_CLANG_MIN(x, y) \
+ (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
+#else
+#define UPB_CLANG_MIN(x, y) 0
+#endif
+
// Macros for checking for compiler attributes, defined here to avoid the
// problem described in
// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html.
@@ -601,10 +608,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name; \
- extern type __stop_linkarr_##name; \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name; \
+ extern type __stop_linkarr_##name; \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -615,13 +624,15 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name __asm( \
- "section$start$__DATA$__la_" #name); \
- extern type __stop_linkarr_##name __asm( \
- "section$end$__DATA$" \
- "__la_" #name); \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name __asm( \
+ "section$start$__DATA$__la_" #name); \
+ extern type __stop_linkarr_##name __asm( \
+ "section$end$__DATA$" \
+ "__la_" #name); \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -659,7 +670,9 @@ Error, UINTPTR_MAX is undefined
// Linker arrays are not supported on this platform. Make macros no-ops.
#define UPB_LINKARR_APPEND(name)
-#define UPB_LINKARR_DECLARE(name, type)
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)")
#define UPB_LINKARR_START(name) (NULL)
#define UPB_LINKARR_STOP(name) (NULL)
@@ -676,11 +689,46 @@ Error, UINTPTR_MAX is undefined
#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name)
#endif
-#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define _UPB_STRINGIFY2(x) #x
+#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x)
+
+#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1))
+/*
+ * Workaround for b/456308964 and b/456317163. Although weak constructors
+ * resolve to a single function body, Clang still emits a pointer into
+ * .init_array for every translation unit, causing the constructor to be
+ * executed multiple times and inflating binary size. We wrap the .init_array
+ * entry in a COMDAT group (using inline assembly) to force the linker to
+ * deduplicate the pointer to exactly one instance. %cc is used in preference to
+ * the more widely available %c because %c may under some circumstances still
+ * output a function name including relocation information, which will then
+ * confuse the linker. This was only a problem on gcc; when %cc was introduced
+ * to clang it was just an alias to %c, and clang's %c had already done the
+ * checks that %cc introduced to gcc.
+ * References:
+ * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa
+ * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305
+ */
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
+ __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \
+ void) { \
+ __asm__ volatile( \
+ ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \
+ ".dc.a %cc0\n" \
+ ".popsection\n" \
+ : \
+ : "X"(UPB_PRIVATE(name))); \
+ __VA_ARGS__ \
+ }
+#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \
+ defined(__MINGW32__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
_UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
__attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \
- name)(void)
+ name)(void) { \
+ __VA_ARGS__ \
+ }
#elif defined(_MSC_VER)
/*
* See: https://stackoverflow.com/questions/1113409
@@ -691,17 +739,22 @@ Error, UINTPTR_MAX is undefined
* create a dummy exported weak symbol that prevent this stripping.
*/
#pragma section(".CRT$XCT", read)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
static void __cdecl UPB_PRIVATE(name)(void); \
__declspec(allocate(".CRT$XCT"), selectany) void( \
__cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \
__declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \
&UPB_PRIVATE(name##_); \
- static void __cdecl UPB_PRIVATE(name)(void)
-
+ static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ }
#else
// No constructor support, nothing we can do except not break builds.
-#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void)
+#if defined(__GNUC__) || defined(__clang__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#else
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#endif
#endif
//
@@ -739,9 +792,9 @@ Error, UINTPTR_MAX is undefined
#elif defined(__ELF__) || defined(__wasm__)
-// On ELF, weak aliases work properly, so we can have all weak MiniTables point
-// to the same empty singleton MiniTable. This reduces code size if many
-// MiniTables are tree shaken.
+ // On ELF, weak aliases work properly, so we can have all weak MiniTables
+ // point to the same empty singleton MiniTable. This reduces code size if many
+ // MiniTables are tree shaken.
#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \
__attribute__((weak)) \
const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \
@@ -6845,6 +6898,35 @@ extern const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout;
#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ */
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_
+
+
+// Must be last.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init;
+extern const upb_MiniTableExtension* pb_enumvalue_json_ext;
+
+extern const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ */
#ifndef UPB_BASE_INTERNAL_LOG2_H_
#define UPB_BASE_INTERNAL_LOG2_H_
@@ -15019,6 +15101,7 @@ bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s);
#include
#include
+#include
// Must be last.
@@ -15031,6 +15114,12 @@ bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num);
const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e);
int32_t upb_EnumDef_Default(const upb_EnumDef* e);
UPB_API const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e);
+UPB_API const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(
+ const upb_EnumDef* e, const char* name, size_t size);
+UPB_INLINE const upb_EnumValueDef* upb_EnumDef_FindByJsonName(
+ const upb_EnumDef* e, const char* name) {
+ return upb_EnumDef_FindByJsonNameWithSize(e, name, strlen(name));
+}
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const char* name);
UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
@@ -15073,6 +15162,8 @@ UPB_API int upb_EnumDef_ValueCount(const upb_EnumDef* e);
#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_
#define UPB_REFLECTION_ENUM_VALUE_DEF_H_
+#include
+
// Must be last.
@@ -15084,6 +15175,7 @@ const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v);
const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v);
bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v);
uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v);
+UPB_API const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v);
UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v);
UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v);
const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options(
@@ -18082,7 +18174,8 @@ extern "C" {
#endif
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i);
-bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a);
+void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e,
+ upb_EnumValueDef* v);
const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e);
// Allocate and initialize an array of |n| enum defs.
@@ -18176,6 +18269,151 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a);
#endif /* UPB_REFLECTION_INTERNAL_STRDUP2_H_ */
+#ifndef GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
+#define GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
+
+// IWYU pragma: begin_exports
+
+#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0
+// This header is checked in.
+#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 1
+// This header is generated at build time by the bootstrapping process.
+#else
+// This is the normal header, generated by upb_c_proto_library().
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+
+
+// Must be last.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct pb_enumvalue_JsonEnumValueOptions {
+ upb_Message UPB_PRIVATE(base);
+} pb_enumvalue_JsonEnumValueOptions;
+
+struct google_protobuf_EnumValueOptions;
+
+
+
+/* pb.enumvalue.JsonEnumValueOptions */
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_new(upb_Arena* arena) {
+ return (pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena);
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse(const char* buf, size_t size,
+ upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, NULL, 0,
+ arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse_ex(
+ const char* buf, size_t size, const upb_ExtensionRegistry* extreg,
+ int options, upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, extreg,
+ options, arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize(const pb_enumvalue_JsonEnumValueOptions* msg,
+ upb_Arena* arena, size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, 0, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize_ex(const pb_enumvalue_JsonEnumValueOptions* msg,
+ int options, upb_Arena* arena,
+ size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, options, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_clear_string(pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ upb_Message_ClearBaseField(UPB_UPCAST(msg), &field);
+}
+UPB_INLINE upb_StringView pb_enumvalue_JsonEnumValueOptions_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ upb_StringView default_val = upb_StringView_FromString("");
+ upb_StringView ret;
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field,
+ &default_val, &ret);
+ return ret;
+}
+UPB_INLINE bool pb_enumvalue_JsonEnumValueOptions_has_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ return upb_Message_HasBaseField(UPB_UPCAST(msg), &field);
+}
+
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_set_string(pb_enumvalue_JsonEnumValueOptions* msg, upb_StringView value) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ upb_Message_SetBaseField((upb_Message*)msg, &field, &value);
+}
+
+UPB_INLINE bool pb_enumvalue_has_json(const struct google_protobuf_EnumValueOptions* msg) {
+ return upb_Message_HasExtension((upb_Message*)msg, pb_enumvalue_json_ext);
+}
+
+UPB_INLINE void pb_enumvalue_clear_json(struct google_protobuf_EnumValueOptions* msg) {
+ upb_Message_ClearExtension((upb_Message*)msg, pb_enumvalue_json_ext);
+}
+UPB_INLINE const pb_enumvalue_JsonEnumValueOptions*
+pb_enumvalue_json(const struct google_protobuf_EnumValueOptions* msg) {
+ const upb_MiniTableExtension* ext = pb_enumvalue_json_ext;
+ UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field)));
+ UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(
+ &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
+ const pb_enumvalue_JsonEnumValueOptions* default_val = NULL;
+ const pb_enumvalue_JsonEnumValueOptions* ret;
+ _upb_Message_GetExtensionField((upb_Message*)msg, ext, &default_val, &ret);
+ return ret;
+}
+
+UPB_INLINE void pb_enumvalue_set_json(struct google_protobuf_EnumValueOptions* msg,
+ const pb_enumvalue_JsonEnumValueOptions* val,
+ upb_Arena* arena) {
+ const upb_MiniTableExtension* ext = pb_enumvalue_json_ext;
+ UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field)));
+ UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(
+ &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
+ bool ok = upb_Message_SetExtension((upb_Message*)msg, ext, &val, arena);
+ UPB_ASSERT(ok);
+}
+UPB_INLINE struct pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_mutable_json(
+ struct google_protobuf_EnumValueOptions* msg, upb_Arena* arena) {
+ struct pb_enumvalue_JsonEnumValueOptions* sub = (struct pb_enumvalue_JsonEnumValueOptions*)pb_enumvalue_json(msg);
+ if (sub == NULL) {
+ sub = (struct pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena);
+ if (sub) pb_enumvalue_set_json(msg, sub, arena);
+ }
+ return sub;
+}
+#ifdef __cplusplus
+ } /* extern "C" */
+#endif
+
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ */
+#endif
+
+// IWYU pragma: end_exports
+
+#endif // GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
#ifndef UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_
#define UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_
@@ -18990,6 +19228,7 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) {
#undef UPB_TSAN
#undef UPB_DEPRECATED
#undef UPB_GNUC_MIN
+#undef UPB_CLANG_MIN
#undef UPB_DESCRIPTOR_UPB_H_FILENAME
#undef UPB_DESC_MINITABLE
#undef UPB_IS_GOOGLE3
@@ -19016,3 +19255,6 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) {
#undef UPB_DEPRECATE_AND_INLINE
#undef UPB_MAYBE_ASSUME
#undef UPB_ATTR_CONST
+#undef _UPB_STRINGIFY
+#undef _UPB_STRINGIFY2
+#undef UPB_CONSTRUCTOR
diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec
index 09569635f6..47aabed7f6 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.36.0"
+ s.version = "4.36.0.rc.2"
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 b96c464223..c044254c4d 100644
--- a/ruby/pom.xml
+++ b/ruby/pom.xml
@@ -9,7 +9,7 @@
com.google.protobuf.jruby
protobuf-jruby
- 4.36.0
+ 4.36.0-RC2
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.36.0
+ 4.36.0-RC2
org.jruby
diff --git a/src/file_lists.cmake b/src/file_lists.cmake
index d6a6947228..0029947822 100644
--- a/src/file_lists.cmake
+++ b/src/file_lists.cmake
@@ -848,6 +848,7 @@ set(libupb_hdrs
${protobuf_SOURCE_DIR}/upb/reflection/internal/oneof_def.h
${protobuf_SOURCE_DIR}/upb/reflection/internal/service_def.h
${protobuf_SOURCE_DIR}/upb/reflection/internal/upb_edition_defaults.h
+ ${protobuf_SOURCE_DIR}/upb/reflection/json_enumvalue_options_bootstrap.h
${protobuf_SOURCE_DIR}/upb/reflection/message.h
${protobuf_SOURCE_DIR}/upb/reflection/message.hpp
${protobuf_SOURCE_DIR}/upb/reflection/message_def.h
@@ -988,60 +989,6 @@ set(protoc-gen-upb_minitable_hdrs
${protobuf_SOURCE_DIR}/upb_generator/plugin_bootstrap.h
)
-# @//src/google/protobuf:well_known_type_protos
-set(wkt_protos_files
- ${protobuf_SOURCE_DIR}/src/google/protobuf/any.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/api.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/duration.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/empty.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/timestamp.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/type.proto
- ${protobuf_SOURCE_DIR}/src/google/protobuf/wrappers.proto
-)
-
-# @//src/google/protobuf:cpp_file_options_proto
-set(cpp_file_options_proto_proto_srcs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto
-)
-
-# @//src/google/protobuf:cpp_file_options_proto
-set(cpp_file_options_proto_srcs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto.pb.cc
-)
-
-# @//src/google/protobuf:cpp_file_options_proto
-set(cpp_file_options_proto_hdrs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto.pb.h
-)
-
-# @//src/google/protobuf:cpp_file_options_proto
-set(cpp_file_options_proto_files
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options_proto-descriptor-set.proto.bin
-)
-
-# @//src/google/protobuf:cpp_features_proto
-set(cpp_features_proto_proto_srcs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto
-)
-
-# @//src/google/protobuf:cpp_features_proto
-set(cpp_features_proto_srcs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto.pb.cc
-)
-
-# @//src/google/protobuf:cpp_features_proto
-set(cpp_features_proto_hdrs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto.pb.h
-)
-
-# @//src/google/protobuf:cpp_features_proto
-set(cpp_features_proto_files
- ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features_proto-descriptor-set.proto.bin
-)
-
# @//src/google/protobuf:descriptor_proto
set(descriptor_proto_proto_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.proto
@@ -1062,34 +1009,6 @@ set(descriptor_proto_files
${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_proto-descriptor-set.proto.bin
)
-# @//src/google/protobuf:json_enumvalue_options_proto
-set(json_enumvalue_options_proto_proto_srcs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto
-)
-
-# @//src/google/protobuf:json_enumvalue_options_proto
-set(json_enumvalue_options_proto_srcs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto.pb.cc
-)
-
-# @//src/google/protobuf:json_enumvalue_options_proto
-set(json_enumvalue_options_proto_hdrs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto.pb.h
-)
-
-# @//src/google/protobuf:json_enumvalue_options_proto
-set(json_enumvalue_options_proto_files
- ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options_proto-descriptor-set.proto.bin
-)
-
-# @//src/google/protobuf:json_enumvalue_options_cc_proto
-set(json_enumvalue_options_cc_proto_files
- ${protobuf_SOURCE_DIR}/src/google/protobuf/_virtual_imports/json_enumvalue_options_proto/google/protobuf/json_enumvalue_options.pb.cc
- ${protobuf_SOURCE_DIR}/src/google/protobuf/_virtual_imports/json_enumvalue_options_proto/google/protobuf/json_enumvalue_options.pb.h
- ${protobuf_SOURCE_DIR}/src/google/protobuf/libjson_enumvalue_options_proto.a
- ${protobuf_SOURCE_DIR}/src/google/protobuf/libjson_enumvalue_options_proto.so
-)
-
# @//src/google/protobuf/compiler:plugin_proto
set(plugin_proto_proto_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.proto
@@ -1110,64 +1029,27 @@ set(plugin_proto_files
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin_proto-descriptor-set.proto.bin
)
-# @//csharp:c_sharp_features_proto
-set(c_sharp_features_proto_proto_srcs
+# @//src/google/protobuf:release_all_options_proto_srcs
+set(release_all_options_protos_files
${protobuf_SOURCE_DIR}/csharp/google/protobuf/c_sharp_features.proto
-)
-
-# @//csharp:c_sharp_features_proto
-set(c_sharp_features_proto_srcs
- ${protobuf_SOURCE_DIR}/csharp/google/protobuf/c_sharp_features.proto.pb.cc
-)
-
-# @//csharp:c_sharp_features_proto
-set(c_sharp_features_proto_hdrs
- ${protobuf_SOURCE_DIR}/csharp/google/protobuf/c_sharp_features.proto.pb.h
-)
-
-# @//csharp:c_sharp_features_proto
-set(c_sharp_features_proto_files
- ${protobuf_SOURCE_DIR}/csharp/c_sharp_features_proto-descriptor-set.proto.bin
-)
-
-# @//java/core:java_features_proto
-set(java_features_proto_proto_srcs
- ${protobuf_SOURCE_DIR}/java/core/src/main/resources/google/protobuf/java_features.proto
-)
-
-# @//java/core:java_features_proto
-set(java_features_proto_srcs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_features.proto.pb.cc
-)
-
-# @//java/core:java_features_proto
-set(java_features_proto_hdrs
- ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_features.proto.pb.h
-)
-
-# @//java/core:java_features_proto
-set(java_features_proto_files
- ${protobuf_SOURCE_DIR}/java/core/java_features_proto-descriptor-set.proto.bin
-)
-
-# @//go:go_features_proto
-set(go_features_proto_proto_srcs
${protobuf_SOURCE_DIR}/go/google/protobuf/go_features.proto
-)
-
-# @//go:go_features_proto
-set(go_features_proto_srcs
- ${protobuf_SOURCE_DIR}/go/go_features.proto.pb.cc
-)
-
-# @//go:go_features_proto
-set(go_features_proto_hdrs
- ${protobuf_SOURCE_DIR}/go/go_features.proto.pb.h
-)
-
-# @//go:go_features_proto
-set(go_features_proto_files
- ${protobuf_SOURCE_DIR}/go/go_features_proto-descriptor-set.proto.bin
+ ${protobuf_SOURCE_DIR}/java/core/src/main/resources/google/protobuf/java_features.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/any.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/api.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_options.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/duration.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/empty.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/json_options.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/timestamp.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/type.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/wrappers.proto
)
# @//pkg:common_test
@@ -1288,6 +1170,9 @@ set(upb_test_protos_files
${protobuf_SOURCE_DIR}/src/google/protobuf/duration.proto
${protobuf_SOURCE_DIR}/src/google/protobuf/empty.proto
${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/json/json_enumval_custom_string.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto
+ ${protobuf_SOURCE_DIR}/src/google/protobuf/json_options.proto
${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.proto
${protobuf_SOURCE_DIR}/src/google/protobuf/struct.proto
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto
diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel
index 9fc9be8032..4db3c4e951 100644
--- a/src/google/protobuf/BUILD.bazel
+++ b/src/google/protobuf/BUILD.bazel
@@ -405,6 +405,24 @@ cc_proto_library(
deps = [":json_enumvalue_options_proto"],
)
+upb_c_proto_library(
+ name = "json_enumvalue_options_upb_c_proto",
+ visibility = ["//:__subpackages__"],
+ deps = [":json_enumvalue_options_proto"],
+)
+
+upb_minitable_proto_library(
+ name = "json_enumvalue_options_upb_minitable_proto",
+ visibility = ["//:__subpackages__"],
+ deps = [":json_enumvalue_options_proto"],
+)
+
+upb_proto_reflection_library(
+ name = "json_enumvalue_options_upb_reflection_proto",
+ visibility = ["//:__subpackages__"],
+ deps = [":json_enumvalue_options_proto"],
+)
+
################################################################################
# C++ Runtime Library
################################################################################
@@ -1202,12 +1220,111 @@ filegroup(
visibility = ["//:__subpackages__"],
)
+filegroup(
+ name = "json_enumvalue_options_proto_srcs",
+ srcs = ["json_enumvalue_options.proto"],
+ visibility = ["//:__subpackages__"],
+)
+
filegroup(
name = "cpp_features_proto_srcs",
srcs = ["cpp_features.proto"],
visibility = ["//:__subpackages__"],
)
+# TODO: Revisit location of aggregate rules
+filegroup(
+ name = "language_neutral_proto_srcs",
+ srcs = [
+ ":json_options_proto_srcs",
+ ":well_known_type_protos",
+ ],
+ visibility = [
+ "//ruby:__pkg__",
+ ],
+)
+
+filegroup(
+ name = "release_all_options_proto_srcs",
+ srcs = [
+ ":cpp_release_options_proto_srcs",
+ ":descriptor_proto_srcs",
+ ":language_neutral_proto_srcs",
+ "//csharp:c_sharp_features_proto_srcs",
+ "//go:go_features_proto_srcs",
+ "//java/core:java_features_proto_srcs",
+ ],
+ visibility = [
+ "//java/core:__pkg__",
+ "//pkg:__pkg__",
+ "//python/dist:__pkg__",
+ ],
+)
+
+proto_library(
+ name = "language_neutral_protos",
+ srcs = [":language_neutral_proto_srcs"],
+ strip_import_prefix = "/src",
+ visibility = [
+ "//python/dist:__pkg__",
+ ],
+ exports = [
+ ":descriptor_proto",
+ ],
+ deps = [
+ ":descriptor_proto",
+ ],
+)
+
+proto_library(
+ name = "release_all_options_protos",
+ srcs = [],
+ strip_import_prefix = "/src",
+ visibility = [
+ "//java/core:__pkg__",
+ "//pkg:__pkg__",
+ "//python/dist:__pkg__",
+ ],
+ exports = [
+ ":cpp_release_options_protos",
+ ":descriptor_proto",
+ ":language_neutral_protos",
+ # TODO: Create //lang:lang_release_options_protos targets for each language and
+ # depend on those instead.
+ "//csharp:c_sharp_features_proto",
+ "//go:go_features_proto",
+ "//java/core:java_features_proto",
+ ],
+ deps = [
+ ":cpp_release_options_protos",
+ ":descriptor_proto",
+ ":language_neutral_protos",
+ # TODO: Create //lang:lang_release_options_protos targets for each language and
+ # depend on those instead.
+ "//csharp:c_sharp_features_proto",
+ "//go:go_features_proto",
+ "//java/core:java_features_proto",
+ ],
+)
+
+filegroup(
+ name = "cpp_release_options_proto_srcs",
+ srcs = glob(["cpp_*options.proto"]) + ["cpp_features.proto"],
+)
+
+proto_library(
+ name = "cpp_release_options_protos",
+ srcs = [":cpp_release_options_proto_srcs"],
+ strip_import_prefix = "/src",
+ deps = [":descriptor_proto"],
+)
+
+filegroup(
+ name = "json_options_proto_srcs",
+ srcs = glob(["json_*options.proto"]),
+ visibility = ["//:__subpackages__"],
+)
+
filegroup(
name = "testdata",
srcs = glob(["testdata/**/*"]) + [
@@ -1554,7 +1671,7 @@ exports_files(
"//:__pkg__",
"//python:__pkg__",
"//ruby:__pkg__",
- "//upb:__pkg__",
+ "//upb:__subpackages__",
],
)
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index b9d0279ed1..4d42009c77 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/any.pb.h"
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index c37af3ccc9..1500e855d3 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fany_2eproto_2epb_2eh
#define google_2fprotobuf_2fany_2eproto_2epb_2eh
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index e3f85e4a92..f9411836a3 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/api.pb.h"
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 38af1c21ca..f90d4f2f65 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fapi_2eproto_2epb_2eh
#define google_2fprotobuf_2fapi_2eproto_2epb_2eh
diff --git a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc
index 6a6686982b..71bbbf4860 100755
--- a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc
+++ b/src/google/protobuf/compiler/csharp/c_sharp_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/csharp/c_sharp_features.proto
-// Protobuf C++ Version: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/compiler/csharp/c_sharp_features.pb.h"
diff --git a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h
index be8f038217..285921e70b 100755
--- a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h
+++ b/src/google/protobuf/compiler/csharp/c_sharp_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/csharp/c_sharp_features.proto
-// Protobuf C++ Version: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_2epb_2eh
#define google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_2epb_2eh
diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc
index 542f784144..0cc2fab11e 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#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 fb850f1868..765a509468 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh
#define google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh
diff --git a/src/google/protobuf/compiler/php/generator_unittest.cc b/src/google/protobuf/compiler/php/generator_unittest.cc
index 79d4b10faa..1cfa10bf1a 100644
--- a/src/google/protobuf/compiler/php/generator_unittest.cc
+++ b/src/google/protobuf/compiler/php/generator_unittest.cc
@@ -137,6 +137,22 @@ TEST_F(PhpGeneratorTest, ImportPublic) {
ExpectNoErrors();
}
+// TODO Remove this test once full Edition 2026 support is in PHP
+TEST_F(PhpGeneratorTest, Edition2026Fails) {
+ CreateTempFile("foo.proto",
+ R"schema(
+ edition = "2026";
+ enum Foo {
+ BAR = 0;
+ })schema");
+
+ RunProtoc(
+ "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "PHP does not yet fully support Edition 2026, but is coming soon.");
+}
+
} // namespace
} // namespace php
} // namespace compiler
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc
index 4d85acf18b..66d9966e56 100644
--- a/src/google/protobuf/compiler/php/php_generator.cc
+++ b/src/google/protobuf/compiler/php/php_generator.cc
@@ -2212,6 +2212,12 @@ bool Generator::Generate(const FileDescriptor* file, const Options& options,
"Can only generate PHP code for google/protobuf/descriptor.proto.\n";
return false;
}
+ // TODO Remove once full Edition 2026 support is in PHP
+ if (GetEdition(*file) >= Edition::EDITION_2026) {
+ *error =
+ "PHP does not yet fully support Edition 2026, but is coming soon.\n";
+ return false;
+ }
return GenerateFile(file, options, generator_context, error);
}
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index a7b4f668bf..19b66dedf5 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#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 af8a1d8294..bfe9c4709a 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh
#define google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh
diff --git a/src/google/protobuf/compiler/versions.h b/src/google/protobuf/compiler/versions.h
index e099cca1ba..0d3825606d 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 "7.36.0-dev"
-#define PROTOBUF_JAVA_VERSION_STRING "4.36.0-dev"
-#define PROTOBUF_PYTHON_VERSION_STRING "7.36.0-dev"
-#define PROTOBUF_RUST_VERSION_STRING "4.36.0-dev"
+#define PROTOBUF_CPP_VERSION_STRING "7.36.0-rc2"
+#define PROTOBUF_JAVA_VERSION_STRING "4.36.0-rc2"
+#define PROTOBUF_PYTHON_VERSION_STRING "7.36.0-rc2"
+#define PROTOBUF_RUST_VERSION_STRING "4.36.0-rc2"
namespace google {
diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc
index 9659bac7d9..067ebb9879 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#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 de11ec0398..73e8d23107 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh
#define google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh
diff --git a/src/google/protobuf/cpp_file_options.pb.cc b/src/google/protobuf/cpp_file_options.pb.cc
index f349dd8dcd..f9653bf2cd 100644
--- a/src/google/protobuf/cpp_file_options.pb.cc
+++ b/src/google/protobuf/cpp_file_options.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/cpp_file_options.proto
-// Protobuf C++ Version: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/cpp_file_options.pb.h"
diff --git a/src/google/protobuf/cpp_file_options.pb.h b/src/google/protobuf/cpp_file_options.pb.h
index 606f838360..5df9f78bc8 100644
--- a/src/google/protobuf/cpp_file_options.pb.h
+++ b/src/google/protobuf/cpp_file_options.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/cpp_file_options.proto
-// Protobuf C++ Version: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fcpp_5ffile_5foptions_2eproto_2epb_2eh
#define google_2fprotobuf_2fcpp_5ffile_5foptions_2eproto_2epb_2eh
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 237e4d69bf..b6e391ea94 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -9288,19 +9288,7 @@ void internal::DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo(
}
if (loc_matches) {
- if (loc->path_size() == static_cast(match_src.size() + 1)) {
- int uninterpreted_field = loc->path(match_src.size());
-
- SourceCodeInfo_Location* mapped_loc = new_locs.Add();
- *mapped_loc = *loc;
- mapped_loc->mutable_path()->Assign(match_dest.begin(),
- match_dest.end());
- mapped_loc->add_path(uninterpreted_field);
-
- // TODO: b/168903973 - recursively process options with aggregate
- // values and add locations. Example: [(my_opt) = {a: 1, b: 2}]
- // Locations of `a` and `b` are not added yet.
- }
+ // TODO: b/168903973 - Remove once we update the format.
// don't copy this row since it is a sub-location that we're removing
// (or we already mapped it if it's a direct child)
continue;
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index b4ba33f626..0a7ac37ddb 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/descriptor.pb.h"
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index cd47e1d6a9..1416175c04 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh
#define google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 472ae944cd..e0e7f68082 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -16274,6 +16274,8 @@ TEST_F(SourceLocationTest, GetSourceLocation) {
"rpc Method(A) returns (A.B);"));
}
+// TODO: b/168903973 - Remove once we update the format.
+
TEST_F(SourceLocationTest, ExtensionSourceLocation) {
SourceLocation loc;
@@ -16330,19 +16332,7 @@ TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) {
EXPECT_FALSE(file_desc->GetSourceLocation(unint, &loc));
- SourceCodePath name_path = {FileDescriptorProto::kOptionsFieldNumber,
- FileOptions::kJavaPackageFieldNumber,
- UninterpretedOption::kNameFieldNumber};
- EXPECT_TRUE(file_desc->GetSourceLocation(name_path, &loc));
- EXPECT_THAT(loc,
- MatchesSubstring(kSourceLocationTestInput, "java_package"));
-
- SourceCodePath val_path = {FileDescriptorProto::kOptionsFieldNumber,
- FileOptions::kJavaPackageFieldNumber,
- UninterpretedOption::kStringValueFieldNumber};
- EXPECT_TRUE(file_desc->GetSourceLocation(val_path, &loc));
- EXPECT_THAT(loc,
- MatchesSubstring(kSourceLocationTestInput, "\"com.foo.bar\""));
+// TODO: b/168903973 - Remove once we update the format.
}
{
SourceCodePath path = {FileDescriptorProto::kOptionsFieldNumber,
@@ -16355,18 +16345,7 @@ TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) {
EXPECT_FALSE(file_desc->GetSourceLocation(unint, &loc));
- SourceCodePath name_path = {FileDescriptorProto::kOptionsFieldNumber,
- kCustomOptionFieldNumber,
- UninterpretedOption::kNameFieldNumber};
- EXPECT_TRUE(file_desc->GetSourceLocation(name_path, &loc));
- EXPECT_THAT(loc,
- MatchesSubstring(kSourceLocationTestInput, "(test_file_opt)"));
-
- SourceCodePath val_path = {FileDescriptorProto::kOptionsFieldNumber,
- kCustomOptionFieldNumber,
- UninterpretedOption::kStringValueFieldNumber};
- EXPECT_TRUE(file_desc->GetSourceLocation(val_path, &loc));
- EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, "\"foobar\""));
+// TODO: b/168903973 - Remove once we update the format.
}
// Message option
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index a99539aa07..74b19f5615 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/duration.pb.h"
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 575f3d3595..d8abeac48b 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fduration_2eproto_2epb_2eh
#define google_2fprotobuf_2fduration_2eproto_2epb_2eh
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 851ad8ac4b..087a4232a3 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/empty.pb.h"
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index f20b653a2c..c98ee5a30e 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fempty_2eproto_2epb_2eh
#define google_2fprotobuf_2fempty_2eproto_2epb_2eh
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index bb68a2931c..035e9604c2 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#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 9d3f333097..18aeceb1a9 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh
#define google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh
diff --git a/src/google/protobuf/json/BUILD b/src/google/protobuf/json/BUILD
index 2ab38bce82..1823c07baf 100644
--- a/src/google/protobuf/json/BUILD
+++ b/src/google/protobuf/json/BUILD
@@ -111,7 +111,6 @@ cc_library(
"//src/google/protobuf/stubs",
"@abseil-cpp//absl/algorithm:container",
"@abseil-cpp//absl/log:absl_check",
- "@abseil-cpp//absl/log:absl_log",
"@abseil-cpp//absl/status",
"@abseil-cpp//absl/status:statusor",
"@abseil-cpp//absl/strings",
@@ -293,7 +292,6 @@ cc_library(
"//src/google/protobuf/io:zero_copy_sink",
"//src/google/protobuf/stubs",
"//src/google/protobuf/util:type_resolver",
- "@abseil-cpp//absl/container:flat_hash_map",
"@abseil-cpp//absl/log:absl_check",
"@abseil-cpp//absl/log:absl_log",
"@abseil-cpp//absl/status",
@@ -316,6 +314,11 @@ proto_library(
testonly = True,
srcs = ["json_enumval_custom_string.proto"],
strip_import_prefix = "/src",
+ visibility = [
+ "//:__subpackages__",
+ "//src/google/protobuf:__subpackages__",
+ "//upb:__subpackages__",
+ ],
deps = ["//src/google/protobuf:json_options_proto"],
)
diff --git a/src/google/protobuf/json/json_enumval_custom_string.proto b/src/google/protobuf/json/json_enumval_custom_string.proto
index 317d19a805..980e091454 100644
--- a/src/google/protobuf/json/json_enumval_custom_string.proto
+++ b/src/google/protobuf/json/json_enumval_custom_string.proto
@@ -24,6 +24,7 @@ enum Armor {
ARMOR_SABATON = 7 [(pb.enumvalue.json).string = "sabaton"];
ARMOR_SOLLERET = 7 [(pb.enumvalue.json).string = "sabaton"];
ARMOR_HACHI_MAI_DO = 8 [(pb.enumvalue.json).string = "8"];
+ ARMOR_GREAVES = 9 [(pb.enumvalue.json).string = "ARMOR_GREAVES"];
}
message Knight {
diff --git a/src/google/protobuf/json_enumvalue_options.pb.cc b/src/google/protobuf/json_enumvalue_options.pb.cc
index 9a01a0ff9b..4cbfbdc47f 100644
--- a/src/google/protobuf/json_enumvalue_options.pb.cc
+++ b/src/google/protobuf/json_enumvalue_options.pb.cc
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/json_enumvalue_options.proto
-// Protobuf C++ Version: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/json_enumvalue_options.pb.h"
@@ -212,8 +212,8 @@ const char descriptor_table_protodef_google_2fprotobuf_2fjson_5fenumvalue_5fopti
"scriptor.proto\"(\n\024JsonEnumValueOptions\022\016"
"\n\006string\030\001 \001(\tX\001:\\\n\004json\022!.google.protob"
"uf.EnumValueOptions\030\346\007 \001(\0132\".pb.enumvalu"
- "e.JsonEnumValueOptionsB\006\262\001\003\010\352\007b\010editions"
- "p\351\007"
+ "e.JsonEnumValueOptionsB\006\262\001\003\010\352\007B\032\n\030com.go"
+ "ogle.protobuf.utilb\010editionsp\351\007"
};
static const ::_pbi::DescriptorTable* PROTOBUF_NONNULL const
descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_deps[1] = {
@@ -223,7 +223,7 @@ static ::absl::once_flag descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5
PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto = {
false,
false,
- 243,
+ 271,
descriptor_table_protodef_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto,
"google/protobuf/json_enumvalue_options.proto",
&descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_once,
diff --git a/src/google/protobuf/json_enumvalue_options.pb.h b/src/google/protobuf/json_enumvalue_options.pb.h
index dbe7360e9d..03097f94a5 100644
--- a/src/google/protobuf/json_enumvalue_options.pb.h
+++ b/src/google/protobuf/json_enumvalue_options.pb.h
@@ -1,7 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/json_enumvalue_options.proto
-// Protobuf C++ Version: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_2epb_2eh
#define google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_2epb_2eh
diff --git a/src/google/protobuf/json_enumvalue_options.proto b/src/google/protobuf/json_enumvalue_options.proto
index 34056f7b70..831919b978 100644
--- a/src/google/protobuf/json_enumvalue_options.proto
+++ b/src/google/protobuf/json_enumvalue_options.proto
@@ -11,6 +11,8 @@ package pb.enumvalue;
import "google/protobuf/descriptor.proto";
+option java_package = "com.google.protobuf.util";
+
local message JsonEnumValueOptions {
// Allows user to specify a custom string to use when serializing an enum
// value to JSON.
diff --git a/src/google/protobuf/json_options.proto b/src/google/protobuf/json_options.proto
index 60b03e2d4c..db5c745dac 100644
--- a/src/google/protobuf/json_options.proto
+++ b/src/google/protobuf/json_options.proto
@@ -12,3 +12,5 @@ edition = "2024";
package pb;
import public "google/protobuf/json_enumvalue_options.proto";
+
+option java_package = "com.google.protobuf.util";
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index e881b85753..e0dc16e425 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -633,8 +633,10 @@ class PROTOBUF_EXPORT Reflection final {
const FieldDescriptor* field) const;
[[nodiscard]] std::string GetString(const Message& message,
const FieldDescriptor* field) const;
- [[nodiscard]] const EnumValueDescriptor* GetEnum(
- const Message& message, const FieldDescriptor* field) const;
+ [[nodiscard]] [[deprecated(
+ "Please use GetEnumValue() instead. GetEnum() will be "
+ "removed in Q1 2027.")]] const EnumValueDescriptor*
+ GetEnum(const Message& message, const FieldDescriptor* field) const;
// GetEnumValue() returns an enum field's value as an integer rather than
// an EnumValueDescriptor*. If the integer value does not correspond to a
@@ -818,8 +820,11 @@ class PROTOBUF_EXPORT Reflection final {
[[nodiscard]] std::string GetRepeatedString(const Message& message,
const FieldDescriptor* field,
int index) const;
- [[nodiscard]] const EnumValueDescriptor* GetRepeatedEnum(
- const Message& message, const FieldDescriptor* field, int index) const;
+ [[nodiscard]] [[deprecated(
+ "Please use GetRepeatedEnumValue() instead. GetRepeatedEnum() will be "
+ "removed in Q1 2027.")]] const EnumValueDescriptor*
+ GetRepeatedEnum(const Message& message, const FieldDescriptor* field,
+ int index) const;
// GetRepeatedEnumValue() returns an enum field's value as an integer rather
// than an EnumValueDescriptor*. If the integer value does not correspond to a
// known value descriptor, a new value descriptor is created. (Such a value
diff --git a/src/google/protobuf/retention_test.cc b/src/google/protobuf/retention_test.cc
index 4e0e2e0c3f..ebcf1c16d8 100644
--- a/src/google/protobuf/retention_test.cc
+++ b/src/google/protobuf/retention_test.cc
@@ -226,9 +226,10 @@ TEST(RetentionTest, StripSourceRetentionOptionsWithSourceCodeInfo) {
*pool.FindFileByName("retention.proto"),
/*include_source_code_info=*/true);
+ // TODO: b/168903973 - Remove once we update the format.
// The number of locations is reduced by the number of stripped elements.
EXPECT_EQ(file_descriptor.source_code_info().location_size(), 88);
- EXPECT_EQ(stripped_file.source_code_info().location_size(), 73);
+ EXPECT_EQ(stripped_file.source_code_info().location_size(), 63);
}
TEST(RetentionTest, RemoveEmptyOptions) {
diff --git a/src/google/protobuf/runtime_version.h b/src/google/protobuf/runtime_version.h
index 2977328a8e..687407a384 100644
--- a/src/google/protobuf/runtime_version.h
+++ b/src/google/protobuf/runtime_version.h
@@ -19,7 +19,7 @@
// The OSS versions are not stripped to avoid merging conflicts.
#define PROTOBUF_OSS_VERSION 7036000
-#define PROTOBUF_OSS_VERSION_SUFFIX "-dev"
+#define PROTOBUF_OSS_VERSION_SUFFIX "-rc2"
#define PROTOBUF_VERSION PROTOBUF_OSS_VERSION
#define PROTOBUF_VERSION_SUFFIX PROTOBUF_OSS_VERSION_SUFFIX
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index bd88c64b77..adc8af801e 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#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 51fdf67503..acc9812f57 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh
#define google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index b239ade12f..769e29aabe 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/struct.pb.h"
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index c1d392209b..c85bc9d31d 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fstruct_2eproto_2epb_2eh
#define google_2fprotobuf_2fstruct_2eproto_2epb_2eh
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index b8930fa066..fd8a304455 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -47,7 +47,7 @@ namespace internal {
#define GOOGLE_PROTOBUF_VERSION 7036000
// A suffix string for alpha, beta or rc releases. Empty for stable releases.
-#define GOOGLE_PROTOBUF_VERSION_SUFFIX "-dev"
+#define GOOGLE_PROTOBUF_VERSION_SUFFIX "-rc2"
// Verifies that the protobuf version a program was compiled with matches what
// it is linked/running with. Use the macro below to call this function.
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index b8b6380057..91cf842808 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/timestamp.pb.h"
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index 0d5026f944..8bdb7f5ddc 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh
#define google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index a4ea02938d..001d734062 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/type.pb.h"
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index c3f5272238..a022a43ff2 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2ftype_2eproto_2epb_2eh
#define google_2fprotobuf_2ftype_2eproto_2epb_2eh
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index 56d76d8c4f..e345a3aaa0 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#include "google/protobuf/wrappers.pb.h"
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 4b1b67b7f4..53edfcf909 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: 7.36.0-dev
+// Protobuf C++ Version: 7.36.0-rc2
#ifndef google_2fprotobuf_2fwrappers_2eproto_2epb_2eh
#define google_2fprotobuf_2fwrappers_2eproto_2epb_2eh
diff --git a/upb/BUILD b/upb/BUILD
index 46e15d01a5..b33477efda 100644
--- a/upb/BUILD
+++ b/upb/BUILD
@@ -32,8 +32,10 @@ UPB_CONFIG_VISIBILITY = [
"//hpb_generator:__subpackages__",
"//lua:__pkg__",
"//python:__pkg__",
+ "//src/google/protobuf/compiler:__subpackages__",
"//upb:__subpackages__",
"//upb_generator:__subpackages__",
+ "//src/google/protobuf/compiler:__subpackages__",
]
config_setting(
@@ -159,6 +161,8 @@ upb_amalgamation(
":generated_code_support",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_c_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_minitable_proto",
"//upb/base",
"//upb/base:internal",
"//upb/hash:hash",
@@ -179,6 +183,7 @@ upb_amalgamation(
"//upb/port",
"//upb/reflection",
"//upb/reflection:descriptor_upb_proto",
+ "//upb/reflection:json_enumvalue_options_upb_proto",
"//upb/reflection:internal",
"//upb/text:debug",
"//upb/text:internal",
@@ -216,6 +221,9 @@ upb_amalgamation(
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
"//src/google/protobuf:descriptor_upb_reflection_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_c_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_minitable_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_reflection_proto",
"//upb/base",
"//upb/base:internal",
"//upb/hash:hash",
@@ -237,6 +245,7 @@ upb_amalgamation(
"//upb/port",
"//upb/reflection",
"//upb/reflection:descriptor_upb_proto",
+ "//upb/reflection:json_enumvalue_options_upb_proto",
"//upb/reflection:internal",
"//upb/wire",
"//upb/wire:back_alloc",
@@ -271,6 +280,8 @@ upb_amalgamation(
":generated_code_support",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_c_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_minitable_proto",
"//upb/base",
"//upb/base:internal",
"//upb/hash:hash",
@@ -292,6 +303,7 @@ upb_amalgamation(
"//upb/port",
"//upb/reflection",
"//upb/reflection:descriptor_upb_proto",
+ "//upb/reflection:json_enumvalue_options_upb_proto",
"//upb/reflection:internal",
"//upb/util:def_to_proto",
"//upb/wire",
@@ -336,6 +348,7 @@ filegroup(
filegroup(
name = "test_protos",
+ testonly = 1,
srcs = [
"//src/google/protobuf:test_messages_proto2.proto",
"//src/google/protobuf:test_messages_proto3.proto",
diff --git a/upb/cmake/BUILD.bazel b/upb/cmake/BUILD.bazel
index 7a574374ed..d035a12c33 100644
--- a/upb/cmake/BUILD.bazel
+++ b/upb/cmake/BUILD.bazel
@@ -26,11 +26,16 @@ genrule(
srcs = [
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_c_proto",
+ "//src/google/protobuf:json_enumvalue_options_upb_minitable_proto",
],
outs = [
"generated-in/google/protobuf/descriptor.upb.h",
"generated-in/google/protobuf/descriptor.upb_minitable.c",
"generated-in/google/protobuf/descriptor.upb_minitable.h",
+ "generated-in/google/protobuf/json_enumvalue_options.upb.h",
+ "generated-in/google/protobuf/json_enumvalue_options.upb_minitable.c",
+ "generated-in/google/protobuf/json_enumvalue_options.upb_minitable.h",
],
cmd = "cp $(SRCS) $(@D)/generated-in/google/protobuf",
)
diff --git a/upb/json/BUILD b/upb/json/BUILD
index 1c766f2c0d..d41037ecb1 100644
--- a/upb/json/BUILD
+++ b/upb/json/BUILD
@@ -42,6 +42,8 @@ cc_test(
srcs = ["decode_test.cc"],
deps = [
":json",
+ ":json_enumval_custom_string_upb_proto",
+ ":json_enumval_custom_string_upb_reflection_proto",
":test_upb_proto",
":test_upb_proto_reflection",
"//:any_upb_proto",
@@ -49,6 +51,7 @@ cc_test(
"//:struct_upb_proto",
"//upb/base",
"//upb/mem",
+ "//upb/message",
"//upb/reflection",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -60,6 +63,8 @@ cc_test(
srcs = ["encode_test.cc"],
deps = [
":json",
+ ":json_enumval_custom_string_upb_proto",
+ ":json_enumval_custom_string_upb_reflection_proto",
":test_upb_proto",
":test_upb_proto_reflection",
"//:any_upb_proto",
@@ -67,6 +72,7 @@ cc_test(
"//:struct_upb_proto",
"//upb/base",
"//upb/mem",
+ "//upb/message",
"//upb/reflection",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -96,6 +102,18 @@ upb_proto_reflection_library(
deps = [":test_proto"],
)
+upb_c_proto_library(
+ name = "json_enumval_custom_string_upb_proto",
+ testonly = 1,
+ deps = ["//src/google/protobuf/json:json_enumval_custom_string_proto"],
+)
+
+upb_proto_reflection_library(
+ name = "json_enumval_custom_string_upb_reflection_proto",
+ testonly = 1,
+ deps = ["//src/google/protobuf/json:json_enumval_custom_string_proto"],
+)
+
filegroup(
name = "test_srcs",
srcs = glob(
@@ -109,10 +127,15 @@ filegroup(
filegroup(
name = "test_protos",
+ testonly = 1,
srcs = glob(
[
"**/*test.proto",
],
- ),
+ ) + [
+ "//src/google/protobuf:json_enumvalue_options.proto",
+ "//src/google/protobuf:json_options.proto",
+ "//src/google/protobuf/json:json_enumval_custom_string_proto_srcs",
+ ],
visibility = ["//upb:__pkg__"],
)
diff --git a/upb/json/decode.c b/upb/json/decode.c
index 39fcdf124b..d168797ab2 100644
--- a/upb/json/decode.c
+++ b/upb/json/decode.c
@@ -830,7 +830,7 @@ static upb_JsonMessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) {
upb_StringView str = jsondec_string(d);
const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f);
const upb_EnumValueDef* ev =
- upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size);
+ upb_EnumDef_FindByJsonNameWithSize(e, str.data, str.size);
upb_JsonMessageValue val = {.ignore = false};
if (ev) {
val.value.int32_val = upb_EnumValueDef_Number(ev);
diff --git a/upb/json/decode_test.cc b/upb/json/decode_test.cc
index 719296da0c..777484d1ad 100644
--- a/upb/json/decode_test.cc
+++ b/upb/json/decode_test.cc
@@ -7,38 +7,61 @@
#include "upb/json/decode.h"
+#include
#include
#include
-#include "google/protobuf/struct.upb.h"
#include
+#include "google/protobuf/json/json_enumval_custom_string.upb.h"
+#include "google/protobuf/json/json_enumval_custom_string.upbdefs.h"
#include "upb/base/status.hpp"
#include "upb/base/upcast.h"
#include "upb/json/test.upb.h"
#include "upb/json/test.upbdefs.h"
#include "upb/mem/arena.h"
#include "upb/mem/arena.hpp"
+#include "upb/message/message.h"
+#include "upb/reflection/def.h"
#include "upb/reflection/def.hpp"
-static upb_test_Box* JsonDecode(const char* json, upb_Arena* a) {
+static bool JsonDecodeGeneric(const char* json, upb_Message* msg,
+ const upb_MessageDef* (*getmsgdef)(upb_DefPool*),
+ upb_Arena* arena) {
upb::Status status;
upb::DefPool defpool;
- upb::MessageDefPtr m(upb_test_Box_getmsgdef(defpool.ptr()));
- EXPECT_TRUE(m.ptr() != nullptr);
+ const upb_MessageDef* m = getmsgdef(defpool.ptr());
+ EXPECT_TRUE(m != nullptr);
- upb_test_Box* box = upb_test_Box_new(a);
int options = 0;
- bool ok = upb_JsonDecode(json, strlen(json), UPB_UPCAST(box), m.ptr(),
- defpool.ptr(), options, a, status.ptr());
- return ok ? box : nullptr;
+ return upb_JsonDecode(json, strlen(json), msg, m, defpool.ptr(), options,
+ arena, status.ptr());
+}
+
+static upb_test_Box* JsonDecode(const char* json, upb_Arena* a) {
+ upb_test_Box* box = upb_test_Box_new(a);
+ if (JsonDecodeGeneric(json, UPB_UPCAST(box), upb_test_Box_getmsgdef, a)) {
+ return box;
+ }
+ return nullptr;
+}
+
+static json_enumval_custom_string_Knight* JsonDecodeKnight(const char* json,
+ upb_Arena* a) {
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a);
+ if (JsonDecodeGeneric(json, UPB_UPCAST(knight),
+ json_enumval_custom_string_Knight_getmsgdef, a)) {
+ return knight;
+ }
+ return nullptr;
}
struct FloatTest {
- const std::string json;
+ const char* json;
float f;
};
-static const std::vector FloatTestsPass = {
+static const FloatTest kFloatTestsPass[] = {
{R"({"f": 0})", 0},
{R"({"f": 1})", 1},
{R"({"f": 1.000000})", 1},
@@ -53,7 +76,7 @@ static const std::vector FloatTestsPass = {
-340282346638528859811704183484516925440.0},
};
-static const std::vector FloatTestsFail = {
+static const FloatTest kFloatTestsFail[] = {
{R"({"f": 1z})", 0},
{R"({"f": 3.4028236e+38})", 0},
{R"({"f": -3.4028236e+38})", 0},
@@ -63,15 +86,15 @@ static const std::vector FloatTestsFail = {
TEST(JsonTest, DecodeFloats) {
upb::Arena a;
- for (const auto& test : FloatTestsPass) {
- upb_test_Box* box = JsonDecode(test.json.c_str(), a.ptr());
+ for (const auto& test : kFloatTestsPass) {
+ upb_test_Box* box = JsonDecode(test.json, a.ptr());
EXPECT_NE(box, nullptr);
float f = upb_test_Box_f(box);
EXPECT_EQ(f, test.f);
}
- for (const auto& test : FloatTestsFail) {
- upb_test_Box* box = JsonDecode(test.json.c_str(), a.ptr());
+ for (const auto& test : kFloatTestsFail) {
+ upb_test_Box* box = JsonDecode(test.json, a.ptr());
EXPECT_EQ(box, nullptr);
}
}
@@ -111,6 +134,181 @@ TEST(JsonTest, RejectsBase64WithHighBitBytes) {
EXPECT_EQ(box, nullptr);
}
+// Test decoding when the enum value has no custom string option set, falling
+// back to the default enum value name.
+TEST(JsonTest, DecodeEnumMissingCustomStringOption) {
+ upb::Arena a;
+ std::string json = R"({"armor":"ARMOR_GORGET"})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_GORGET,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding when a standard custom string option is provided.
+TEST(JsonTest, DecodeEnumWithCustomString) {
+ upb::Arena a;
+ std::string json = R"({"armor":"gr8 helm"})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_GREAT_HELM,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding when the custom string option contains escaped double quotes.
+TEST(JsonTest, DecodeEnumCustomStringWithEscapedQuotes) {
+ upb::Arena a;
+ std::string json = "{\"armor\":\"a\\\"b\"}";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_GAUNTLET,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding when the custom string option is an empty string ("").
+TEST(JsonTest, DecodeEnumEmptyCustomString) {
+ upb::Arena a;
+ std::string json = R"({"armor":""})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_COIF,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding when the custom string option contains escaped control
+// characters (tab and newline).
+TEST(JsonTest, DecodeEnumCustomStringWithEscapedControlChars) {
+ upb::Arena a;
+ std::string json = R"({"armor":"p\taul\ndron"})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_PAULDRON,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding an enum value passed as a raw integer literal.
+TEST(JsonTest, DecodeEnumFromIntegerLiteral) {
+ upb::Arena a;
+ std::string json = R"({"armor":1})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_GREAT_HELM,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding by raw enum name even when a custom string option is defined.
+TEST(JsonTest, DecodeEnumRawNameWhenCustomStringDefined) {
+ upb::Arena a;
+ std::string json = R"({"armor":"ARMOR_GREAT_HELM"})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_GREAT_HELM,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding when the custom string option is enclosed within double quotes.
+TEST(JsonTest, DecodeEnumCustomStringEnclosedInQuotes) {
+ upb::Arena a;
+ std::string json = "{\"armor\":\"\\\"plate\\\"\"}";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_PLATE,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding a custom string that maps to aliased enum values.
+TEST(JsonTest, DecodeEnumAliasedCustomString) {
+ upb::Arena a;
+ std::string json = R"({"armor":"sabaton"})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_SABATON,
+ json_enumval_custom_string_Knight_armor(knight));
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_SOLLERET,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding when the custom string option consists of numeric digits ("8").
+TEST(JsonTest, DecodeEnumNumericCustomString) {
+ upb::Arena a;
+ std::string json = R"({"armor":"8"})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_HACHI_MAI_DO,
+ json_enumval_custom_string_Knight_armor(knight));
+}
+
+// Test decoding an enum value whose custom string option is identical to its
+// original enum value name. Also verify that normal name lookup by original
+// name is not marked as JSON-only.
+TEST(JsonTest, DecodeEnumCustomStringSameAsName) {
+ upb::Arena a;
+ std::string json = R"({"armor":"ARMOR_GREAVES"})";
+ json_enumval_custom_string_Knight* knight =
+ JsonDecodeKnight(json.c_str(), a.ptr());
+ EXPECT_NE(knight, nullptr);
+ EXPECT_EQ(json_enumval_custom_string_ARMOR_GREAVES,
+ json_enumval_custom_string_Knight_armor(knight));
+
+ upb::DefPool defpool;
+ const upb_MessageDef* m =
+ json_enumval_custom_string_Knight_getmsgdef(defpool.ptr());
+ ASSERT_NE(m, nullptr);
+ const upb_FieldDef* f = upb_MessageDef_FindFieldByName(m, "armor");
+ ASSERT_NE(f, nullptr);
+ const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f);
+ ASSERT_NE(e, nullptr);
+ const upb_EnumValueDef* ev = upb_EnumDef_FindValueByName(e, "ARMOR_GREAVES");
+ ASSERT_NE(ev, nullptr);
+ EXPECT_EQ(upb_EnumValueDef_Number(ev),
+ json_enumval_custom_string_ARMOR_GREAVES);
+}
+
+// Test that decoding fails on case mismatch against a custom string.
+TEST(JsonTest, DecodeEnumCustomStringCaseMismatchFails) {
+ upb::Arena a;
+ std::string json = "{\"armor\":\"A\\\"b\"}";
+ EXPECT_EQ(JsonDecodeKnight(json.c_str(), a.ptr()), nullptr);
+}
+
+// Test that decoding fails on case mismatch against a raw enum name.
+TEST(JsonTest, DecodeEnumRawNameCaseMismatchFails) {
+ upb::Arena a;
+ std::string json = R"({"armor":"armor_GAUNtlet"})";
+ EXPECT_EQ(JsonDecodeKnight(json.c_str(), a.ptr()), nullptr);
+}
+
+// Test that decoding fails on an unknown enum value string.
+TEST(JsonTest, DecodeEnumUnknownStringFails) {
+ upb::Arena a;
+ std::string json = R"({"armor":"UNKNOWN_1"})";
+ EXPECT_EQ(JsonDecodeKnight(json.c_str(), a.ptr()), nullptr);
+}
+
+// Test that decoding fails when the JSON payload is an array.
+TEST(JsonTest, DecodeEnumInvalidArrayPayloadFails) {
+ upb::Arena a;
+ std::string json = R"({"armor":["gr8 helm"]})";
+ EXPECT_EQ(JsonDecodeKnight(json.c_str(), a.ptr()), nullptr);
+}
+
+// Test that decoding fails when the JSON payload is a boolean.
+TEST(JsonTest, DecodeEnumInvalidBooleanPayloadFails) {
+ upb::Arena a;
+ std::string json = R"({"armor":true})";
+ EXPECT_EQ(JsonDecodeKnight(json.c_str(), a.ptr()), nullptr);
+}
+
#include "upb/mem/alloc.h"
struct FailAfterAlloc {
diff --git a/upb/json/encode.c b/upb/json/encode.c
index 3bc2f04d58..c0cd54f82f 100644
--- a/upb/json/encode.c
+++ b/upb/json/encode.c
@@ -7,16 +7,25 @@
#include "upb/json/encode.h"
-#include
#include
#include
#include
+#include
#include
+#include
#include
+#include "upb/base/descriptor_constants.h"
+#include "upb/base/status.h"
+#include "upb/base/string_view.h"
#include "upb/lex/round_trip.h"
+#include "upb/mem/arena.h"
+#include "upb/message/array.h"
#include "upb/message/map.h"
+#include "upb/message/message.h"
+#include "upb/mini_table/message.h"
#include "upb/port/vsnprintf_compat.h"
+#include "upb/reflection/def.h"
#include "upb/reflection/message.h"
#include "upb/wire/decode.h"
@@ -44,6 +53,7 @@ static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg,
const upb_MessageDef* m, bool first);
static void jsonenc_value(jsonenc* e, const upb_Message* msg,
const upb_MessageDef* m);
+static void jsonenc_string(jsonenc* e, upb_StringView str);
UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) {
upb_Status_SetErrorMessage(e->status, msg);
@@ -205,7 +215,8 @@ static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) {
: upb_EnumDef_FindValueByNumber(e_def, val);
if (ev) {
- jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev));
+ const char* name = upb_EnumValueDef_JsonName(ev);
+ jsonenc_string(e, upb_StringView_FromString(name));
} else {
jsonenc_printf(e, "%" PRId32, val);
}
diff --git a/upb/json/encode_test.cc b/upb/json/encode_test.cc
index 42ce6dde4d..9f2b30f0c8 100644
--- a/upb/json/encode_test.cc
+++ b/upb/json/encode_test.cc
@@ -12,31 +12,47 @@
#include "google/protobuf/struct.upb.h"
#include
+#include "google/protobuf/json/json_enumval_custom_string.upb.h"
+#include "google/protobuf/json/json_enumval_custom_string.upbdefs.h"
#include "upb/base/status.hpp"
#include "upb/base/upcast.h"
#include "upb/json/test.upb.h"
#include "upb/json/test.upbdefs.h"
#include "upb/mem/arena.h"
#include "upb/mem/arena.hpp"
+#include "upb/message/message.h"
+#include "upb/reflection/def.h"
#include "upb/reflection/def.hpp"
-static std::string JsonEncode(const upb_test_Box* msg, int options) {
+static std::string JsonEncodeGeneric(
+ const upb_Message* msg, const upb_MessageDef* (*getmsgdef)(upb_DefPool*),
+ int options) {
upb::Arena a;
upb::Status status;
upb::DefPool defpool;
- upb::MessageDefPtr m(upb_test_Box_getmsgdef(defpool.ptr()));
- EXPECT_TRUE(m.ptr() != nullptr);
+ const upb_MessageDef* m = getmsgdef(defpool.ptr());
+ EXPECT_TRUE(m != nullptr);
- size_t json_size = upb_JsonEncode(UPB_UPCAST(msg), m.ptr(), defpool.ptr(),
- options, nullptr, 0, status.ptr());
+ size_t json_size =
+ upb_JsonEncode(msg, m, defpool.ptr(), options, nullptr, 0, status.ptr());
char* json_buf = (char*)upb_Arena_Malloc(a.ptr(), json_size + 1);
- size_t size = upb_JsonEncode(UPB_UPCAST(msg), m.ptr(), defpool.ptr(), options,
- json_buf, json_size + 1, status.ptr());
+ size_t size = upb_JsonEncode(msg, m, defpool.ptr(), options, json_buf,
+ json_size + 1, status.ptr());
EXPECT_EQ(size, json_size);
return std::string(json_buf, json_size);
}
+static std::string JsonEncode(const upb_test_Box* msg, int options) {
+ return JsonEncodeGeneric(UPB_UPCAST(msg), upb_test_Box_getmsgdef, options);
+}
+
+static std::string JsonEncodeKnight(
+ const json_enumval_custom_string_Knight* msg, int options) {
+ return JsonEncodeGeneric(
+ UPB_UPCAST(msg), json_enumval_custom_string_Knight_getmsgdef, options);
+}
+
// Encode a single optional enum.
TEST(JsonTest, EncodeEnum) {
upb::Arena a;
@@ -96,3 +112,111 @@ TEST(JsonTest, EncodeConflictJsonName) {
upb_test_Box_set_new_value(new_box, 2);
EXPECT_EQ(R"({"value":2})", JsonEncode(new_box, 0));
}
+
+// Test encoding when the enum value has no custom string option set, verifying
+// it falls back to the default enum value name ("ARMOR_GORGET").
+TEST(JsonTest, EncodeEnumMissingCustomStringOption) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_GORGET);
+ EXPECT_EQ(R"({"armor":"ARMOR_GORGET"})", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding when a standard custom string option is defined ("gr8 helm").
+TEST(JsonTest, EncodeEnumWithCustomString) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_GREAT_HELM);
+ EXPECT_EQ(R"({"armor":"gr8 helm"})", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding when the custom string option contains double quotes requiring
+// escaping ("a\"b").
+TEST(JsonTest, EncodeEnumCustomStringWithEscapedQuotes) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_GAUNTLET);
+ EXPECT_EQ("{\"armor\":\"a\\\"b\"}", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding when the custom string option is enclosed within double quotes
+// ("\"plate\"").
+TEST(JsonTest, EncodeEnumCustomStringEnclosedInQuotes) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_PLATE);
+ EXPECT_EQ("{\"armor\":\"\\\"plate\\\"\"}", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding when the custom string option is an empty string ("").
+TEST(JsonTest, EncodeEnumEmptyCustomString) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_COIF);
+ EXPECT_EQ(R"({"armor":""})", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding when the custom string option contains control characters (tab
+// and newline) requiring escaping ("p\taul\ndron").
+TEST(JsonTest, EncodeEnumCustomStringWithEscapedControlChars) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_PAULDRON);
+ EXPECT_EQ(R"({"armor":"p\taul\ndron"})", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding an enum value that has aliased values sharing a custom string
+// option ("sabaton").
+TEST(JsonTest, EncodeEnumAliasedCustomString) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_SABATON);
+ EXPECT_EQ(R"({"armor":"sabaton"})", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding when the custom string option consists of numeric digits ("8").
+TEST(JsonTest, EncodeEnumNumericCustomString) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_HACHI_MAI_DO);
+ EXPECT_EQ(R"({"armor":"8"})", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding an enum value whose custom string option is identical to its
+// original enum value name.
+TEST(JsonTest, EncodeEnumCustomStringSameAsName) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_GREAVES);
+ EXPECT_EQ(R"({"armor":"ARMOR_GREAVES"})", JsonEncodeKnight(knight, 0));
+}
+
+// Test encoding when upb_JsonEncode_FormatEnumsAsIntegers is set, verifying
+// integer format option overrides the custom string option.
+TEST(JsonTest, EncodeEnumWithIntegerFormatOverride) {
+ upb::Arena a;
+ json_enumval_custom_string_Knight* knight =
+ json_enumval_custom_string_Knight_new(a.ptr());
+ json_enumval_custom_string_Knight_set_armor(
+ knight, json_enumval_custom_string_ARMOR_GREAT_HELM);
+ EXPECT_EQ(R"({"armor":1})",
+ JsonEncodeKnight(knight, upb_JsonEncode_FormatEnumsAsIntegers));
+}
diff --git a/upb/port/def.inc b/upb/port/def.inc
index 621ff38349..00446964f9 100644
--- a/upb/port/def.inc
+++ b/upb/port/def.inc
@@ -42,6 +42,13 @@
#define UPB_GNUC_MIN(x, y) 0
#endif
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define UPB_CLANG_MIN(x, y) \
+ (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y))
+#else
+#define UPB_CLANG_MIN(x, y) 0
+#endif
+
// Macros for checking for compiler attributes, defined here to avoid the
// problem described in
// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html.
@@ -606,10 +613,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name; \
- extern type __stop_linkarr_##name; \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name; \
+ extern type __stop_linkarr_##name; \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -620,13 +629,15 @@ Error, UINTPTR_MAX is undefined
#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
-#define UPB_LINKARR_DECLARE(name, type) \
- extern type __start_linkarr_##name __asm( \
- "section$start$__DATA$__la_" #name); \
- extern type __stop_linkarr_##name __asm( \
- "section$end$__DATA$" \
- "__la_" #name); \
- UPB_LINKARR_APPEND(name) \
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)"); \
+ extern type __start_linkarr_##name __asm( \
+ "section$start$__DATA$__la_" #name); \
+ extern type __stop_linkarr_##name __asm( \
+ "section$end$__DATA$" \
+ "__la_" #name); \
+ UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)
@@ -664,7 +675,9 @@ Error, UINTPTR_MAX is undefined
// Linker arrays are not supported on this platform. Make macros no-ops.
#define UPB_LINKARR_APPEND(name)
-#define UPB_LINKARR_DECLARE(name, type)
+#define UPB_LINKARR_DECLARE(name, type) \
+ UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \
+ "Linker array name too long for Mach-O (16-char limit)")
#define UPB_LINKARR_START(name) (NULL)
#define UPB_LINKARR_STOP(name) (NULL)
@@ -681,11 +694,46 @@ Error, UINTPTR_MAX is undefined
#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name)
#endif
-#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define _UPB_STRINGIFY2(x) #x
+#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x)
+
+#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1))
+/*
+ * Workaround for b/456308964 and b/456317163. Although weak constructors
+ * resolve to a single function body, Clang still emits a pointer into
+ * .init_array for every translation unit, causing the constructor to be
+ * executed multiple times and inflating binary size. We wrap the .init_array
+ * entry in a COMDAT group (using inline assembly) to force the linker to
+ * deduplicate the pointer to exactly one instance. %cc is used in preference to
+ * the more widely available %c because %c may under some circumstances still
+ * output a function name including relocation information, which will then
+ * confuse the linker. This was only a problem on gcc; when %cc was introduced
+ * to clang it was just an alias to %c, and clang's %c had already done the
+ * checks that %cc introduced to gcc.
+ * References:
+ * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa
+ * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305
+ */
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
+ __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \
+ void) { \
+ __asm__ volatile( \
+ ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \
+ ".dc.a %cc0\n" \
+ ".popsection\n" \
+ : \
+ : "X"(UPB_PRIVATE(name))); \
+ __VA_ARGS__ \
+ }
+#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \
+ defined(__MINGW32__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
_UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \
__attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \
- name)(void)
+ name)(void) { \
+ __VA_ARGS__ \
+ }
#elif defined(_MSC_VER)
/*
* See: https://stackoverflow.com/questions/1113409
@@ -696,17 +744,22 @@ Error, UINTPTR_MAX is undefined
* create a dummy exported weak symbol that prevent this stripping.
*/
#pragma section(".CRT$XCT", read)
-#define UPB_CONSTRUCTOR(name, unique_name) \
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
static void __cdecl UPB_PRIVATE(name)(void); \
__declspec(allocate(".CRT$XCT"), selectany) void( \
__cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \
__declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \
&UPB_PRIVATE(name##_); \
- static void __cdecl UPB_PRIVATE(name)(void)
-
+ static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ }
#else
// No constructor support, nothing we can do except not break builds.
-#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void)
+#if defined(__GNUC__) || defined(__clang__)
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#else
+#define UPB_CONSTRUCTOR(name, unique_name, ...) \
+ static void UPB_PRIVATE(name)(void) { __VA_ARGS__ }
+#endif
#endif
//
@@ -744,9 +797,9 @@ Error, UINTPTR_MAX is undefined
#elif defined(__ELF__) || defined(__wasm__)
-// On ELF, weak aliases work properly, so we can have all weak MiniTables point
-// to the same empty singleton MiniTable. This reduces code size if many
-// MiniTables are tree shaken.
+ // On ELF, weak aliases work properly, so we can have all weak MiniTables
+ // point to the same empty singleton MiniTable. This reduces code size if many
+ // MiniTables are tree shaken.
#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \
__attribute__((weak)) \
const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \
diff --git a/upb/port/undef.inc b/upb/port/undef.inc
index 79391ba03c..a2bf8a6be0 100644
--- a/upb/port/undef.inc
+++ b/upb/port/undef.inc
@@ -64,6 +64,7 @@
#undef UPB_TSAN
#undef UPB_DEPRECATED
#undef UPB_GNUC_MIN
+#undef UPB_CLANG_MIN
#undef UPB_DESCRIPTOR_UPB_H_FILENAME
#undef UPB_DESC_MINITABLE
#undef UPB_IS_GOOGLE3
@@ -90,3 +91,6 @@
#undef UPB_DEPRECATE_AND_INLINE
#undef UPB_MAYBE_ASSUME
#undef UPB_ATTR_CONST
+#undef _UPB_STRINGIFY
+#undef _UPB_STRINGIFY2
+#undef UPB_CONSTRUCTOR
diff --git a/upb/reflection/BUILD b/upb/reflection/BUILD
index 8c99c216c7..ea67a152d4 100644
--- a/upb/reflection/BUILD
+++ b/upb/reflection/BUILD
@@ -34,6 +34,19 @@ bootstrap_upb_proto_library(
strip_prefix = "third_party/protobuf/github/bootstrap/src",
)
+bootstrap_upb_proto_library(
+ name = "json_enumvalue_options_upb_proto",
+ bootstrap_hdr = "json_enumvalue_options_bootstrap.h",
+ proto_lib_deps = ["//src/google/protobuf:json_enumvalue_options_proto"],
+ src_files = ["google/protobuf/json_enumvalue_options.proto"],
+ src_rules = [
+ "//:descriptor_proto_srcs",
+ "//:json_enumvalue_options_proto_srcs",
+ ],
+ strip_prefix = "third_party/protobuf/github/bootstrap/src",
+ deps = [":descriptor_upb_proto"],
+)
+
bootstrap_cc_library(
name = "reflection",
hdrs = [
@@ -122,7 +135,10 @@ bootstrap_cc_library(
"oneof_def.h",
"service_def.h",
],
- bootstrap_deps = [":descriptor_upb_proto"],
+ bootstrap_deps = [
+ ":descriptor_upb_proto",
+ ":json_enumvalue_options_upb_proto",
+ ],
copts = UPB_DEFAULT_COPTS,
features = UPB_DEFAULT_FEATURES,
visibility = ["//visibility:public"],
diff --git a/upb/reflection/cmake/google/protobuf/descriptor.upb_minitable.c b/upb/reflection/cmake/google/protobuf/descriptor.upb_minitable.c
index ca3672b1db..7cb063b8f0 100644
--- a/upb/reflection/cmake/google/protobuf/descriptor.upb_minitable.c
+++ b/upb/reflection/cmake/google/protobuf/descriptor.upb_minitable.c
@@ -1620,7 +1620,7 @@ const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init = {
},
};
-static const upb_MiniTable *messages_layout[35] = {
+static const upb_MiniTable *messages_layout_google_protobuf_descriptor_proto_upb_file_layout[35] = {
&google__protobuf__FileDescriptorSet_msg_init,
&google__protobuf__FileDescriptorProto_msg_init,
&google__protobuf__DescriptorProto_msg_init,
@@ -1658,7 +1658,7 @@ static const upb_MiniTable *messages_layout[35] = {
&google__protobuf__GeneratedCodeInfo__Annotation_msg_init,
};
-static const upb_MiniTableEnum *enums_layout[21] = {
+static const upb_MiniTableEnum *enums_layout_google_protobuf_descriptor_proto_upb_file_layout[21] = {
&google__protobuf__Edition_enum_init,
&google__protobuf__ExtensionRangeOptions__VerificationState_enum_init,
&google__protobuf__FeatureSet__EnforceNamingStyle_enum_init,
@@ -1683,8 +1683,8 @@ static const upb_MiniTableEnum *enums_layout[21] = {
};
const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = {
- messages_layout,
- enums_layout,
+ messages_layout_google_protobuf_descriptor_proto_upb_file_layout,
+ enums_layout_google_protobuf_descriptor_proto_upb_file_layout,
NULL,
35,
21,
diff --git a/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb.h b/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb.h
new file mode 100644
index 0000000000..5aa718f41e
--- /dev/null
+++ b/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb.h
@@ -0,0 +1,134 @@
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+
+#include "upb/generated_code_support.h"
+#include "google/protobuf/json_enumvalue_options.upb_minitable.h"
+#include "google/protobuf/descriptor.upb_minitable.h"
+
+// Must be last.
+#include "upb/port/def.inc"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct pb_enumvalue_JsonEnumValueOptions {
+ upb_Message UPB_PRIVATE(base);
+} pb_enumvalue_JsonEnumValueOptions;
+
+struct google_protobuf_EnumValueOptions;
+
+
+
+/* pb.enumvalue.JsonEnumValueOptions */
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_new(upb_Arena* arena) {
+ return (pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena);
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse(const char* buf, size_t size,
+ upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, NULL, 0,
+ arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse_ex(
+ const char* buf, size_t size, const upb_ExtensionRegistry* extreg,
+ int options, upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, extreg,
+ options, arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize(const pb_enumvalue_JsonEnumValueOptions* msg,
+ upb_Arena* arena, size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, 0, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize_ex(const pb_enumvalue_JsonEnumValueOptions* msg,
+ int options, upb_Arena* arena,
+ size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, options, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_clear_string(pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ upb_Message_ClearBaseField(UPB_UPCAST(msg), &field);
+}
+UPB_INLINE upb_StringView pb_enumvalue_JsonEnumValueOptions_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ upb_StringView default_val = upb_StringView_FromString("");
+ upb_StringView ret;
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field,
+ &default_val, &ret);
+ return ret;
+}
+UPB_INLINE bool pb_enumvalue_JsonEnumValueOptions_has_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ return upb_Message_HasBaseField(UPB_UPCAST(msg), &field);
+}
+
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_set_string(pb_enumvalue_JsonEnumValueOptions* msg, upb_StringView value) {
+ const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)};
+ upb_Message_SetBaseField((upb_Message*)msg, &field, &value);
+}
+
+UPB_INLINE bool pb_enumvalue_has_json(const struct google_protobuf_EnumValueOptions* msg) {
+ return upb_Message_HasExtension((upb_Message*)msg, pb_enumvalue_json_ext);
+}
+
+UPB_INLINE void pb_enumvalue_clear_json(struct google_protobuf_EnumValueOptions* msg) {
+ upb_Message_ClearExtension((upb_Message*)msg, pb_enumvalue_json_ext);
+}
+UPB_INLINE const pb_enumvalue_JsonEnumValueOptions*
+pb_enumvalue_json(const struct google_protobuf_EnumValueOptions* msg) {
+ const upb_MiniTableExtension* ext = pb_enumvalue_json_ext;
+ UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field)));
+ UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(
+ &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
+ const pb_enumvalue_JsonEnumValueOptions* default_val = NULL;
+ const pb_enumvalue_JsonEnumValueOptions* ret;
+ _upb_Message_GetExtensionField((upb_Message*)msg, ext, &default_val, &ret);
+ return ret;
+}
+
+UPB_INLINE void pb_enumvalue_set_json(struct google_protobuf_EnumValueOptions* msg,
+ const pb_enumvalue_JsonEnumValueOptions* val,
+ upb_Arena* arena) {
+ const upb_MiniTableExtension* ext = pb_enumvalue_json_ext;
+ UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field)));
+ UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(
+ &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
+ bool ok = upb_Message_SetExtension((upb_Message*)msg, ext, &val, arena);
+ UPB_ASSERT(ok);
+}
+UPB_INLINE struct pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_mutable_json(
+ struct google_protobuf_EnumValueOptions* msg, upb_Arena* arena) {
+ struct pb_enumvalue_JsonEnumValueOptions* sub = (struct pb_enumvalue_JsonEnumValueOptions*)pb_enumvalue_json(msg);
+ if (sub == NULL) {
+ sub = (struct pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena);
+ if (sub) pb_enumvalue_set_json(msg, sub, arena);
+ }
+ return sub;
+}
+#ifdef __cplusplus
+ } /* extern "C" */
+#endif
+
+#include "upb/port/undef.inc"
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ */
diff --git a/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.c b/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.c
new file mode 100644
index 0000000000..0b22505851
--- /dev/null
+++ b/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.c
@@ -0,0 +1,79 @@
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#include
+#include "upb/generated_code_support.h"
+#include "google/protobuf/json_enumvalue_options.upb_minitable.h"
+#include "google/protobuf/descriptor.upb_minitable.h"
+
+// Must be last.
+#include "upb/port/def.inc"
+
+extern const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* UPB_PRIVATE(upb_generated_extension_list);
+typedef struct {
+ upb_MiniTableField fields[1];
+} pb__enumvalue__JsonEnumValueOptions_msg_init_Fields;
+
+static const pb__enumvalue__JsonEnumValueOptions_msg_init_Fields pb_enumvalue_JsonEnumValueOptions__fields = {{
+ {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
+}};
+
+const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init = {
+ &pb_enumvalue_JsonEnumValueOptions__fields.fields[0],
+ UPB_SIZE(24, 32), 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(8), 0,
+#ifdef UPB_TRACING_ENABLED
+ "pb.enumvalue.JsonEnumValueOptions",
+#endif
+ UPB_FASTTABLE_INIT({
+ {0x0000000000000000, &_upb_FastDecoder_DecodeUnknown},
+ {0x001000000000000a, &upb_DecodeFast_String_Scalar_Tag1Byte},
+ })
+};
+
+static const upb_MiniTableExtension pb_enumvalue_json_ext_obj = {
+ {998, 0, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsExtension | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
+ {.UPB_PRIVATE(submsg) = &pb__enumvalue__JsonEnumValueOptions_msg_init},
+ &google__protobuf__EnumValueOptions_msg_init,
+
+};
+UPB_LINKARR_APPEND(upb_AllExts)
+const upb_MiniTableExtension* pb_enumvalue_json_ext = &pb_enumvalue_json_ext_obj;
+ static const upb_MiniTable *messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = {
+ &pb__enumvalue__JsonEnumValueOptions_msg_init,
+};
+
+
+static const upb_MiniTableExtension *extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = {
+ &pb_enumvalue_json_ext_obj,
+};
+
+UPB_LINKARR_DECLARE(upb_AllExts, const upb_MiniTableExtension*);
+UPB_CONSTRUCTOR(upb_GeneratedRegistry_Constructor, google_protobuf_json_enumvalue_options_proto_ext_constructor, {
+ static bool finished = false;
+ if (finished) return;
+ finished = true;
+ static UPB_PRIVATE(upb_GeneratedExtensionListEntry) entry = {
+ UPB_LINKARR_START(upb_AllExts),
+ UPB_LINKARR_STOP(upb_AllExts),
+ NULL
+ };
+ UPB_ASSERT(entry.next == NULL);
+ entry.next = UPB_PRIVATE(upb_generated_extension_list);
+ UPB_PRIVATE(upb_generated_extension_list) = &entry;
+})
+const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout = {
+ messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout,
+ NULL,
+ extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout,
+ 1,
+ 0,
+ 1,
+};
+
+#include "upb/port/undef.inc"
+
diff --git a/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.h b/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.h
new file mode 100644
index 0000000000..97f94e9b3a
--- /dev/null
+++ b/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.h
@@ -0,0 +1,32 @@
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_
+
+#include "upb/generated_code_support.h"
+
+// Must be last.
+#include "upb/port/def.inc"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init;
+extern const upb_MiniTableExtension* pb_enumvalue_json_ext;
+
+extern const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#include "upb/port/undef.inc"
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ */
diff --git a/upb/reflection/def.hpp b/upb/reflection/def.hpp
index c088853f50..bdef384fb3 100644
--- a/upb/reflection/def.hpp
+++ b/upb/reflection/def.hpp
@@ -401,6 +401,7 @@ class EnumValDefPtr {
int32_t number() const { return upb_EnumValueDef_Number(ptr_); }
const char* full_name() const { return upb_EnumValueDef_FullName(ptr_); }
+ const char* json_name() const { return upb_EnumValueDef_JsonName(ptr_); }
const char* name() const { return upb_EnumValueDef_Name(ptr_); }
private:
@@ -452,6 +453,10 @@ class EnumDefPtr {
return EnumValDefPtr(upb_EnumDef_Value(ptr_, i));
}
+ EnumValDefPtr FindValueByJsonName(const char* name) const {
+ return EnumValDefPtr(upb_EnumDef_FindByJsonName(ptr_, name));
+ }
+
// Lookups from name to integer, returning true if found.
EnumValDefPtr FindValueByName(const char* name) const {
return EnumValDefPtr(upb_EnumDef_FindValueByName(ptr_, name));
diff --git a/upb/reflection/enum_def.c b/upb/reflection/enum_def.c
index f0b0d8069c..edf61d7f44 100644
--- a/upb/reflection/enum_def.c
+++ b/upb/reflection/enum_def.c
@@ -54,6 +54,28 @@ struct upb_EnumDef {
bool is_sorted; // Whether all of the values are defined in ascending order.
};
+// We store both regular proto enum names and custom JSON enum names in the
+// same strtable (ntoi). This is safe because protoc enforces that custom JSON
+// enum names never conflict with default enum names across different enum
+// values (or are identical, in which case we leave the entry untagged). Because
+// upb_EnumValueDef pointers are arena-aligned to at least 4 bytes (bit 0 is
+// always 0 for untagged pointers), we set bit 0 to tag custom JSON-only names
+// so that regular name lookups can ignore them.
+static const uintptr_t kUpb_EnumDef_JsonOnlyTag = 1ULL;
+
+static upb_value _upb_EnumDef_TagJsonOnly(upb_value v) {
+ v.val |= kUpb_EnumDef_JsonOnlyTag;
+ return v;
+}
+
+static bool _upb_EnumDef_IsJsonOnly(upb_value v) {
+ return (v.val & kUpb_EnumDef_JsonOnlyTag) != 0;
+}
+
+static const upb_EnumValueDef* _upb_EnumDef_Untag(upb_value v) {
+ return (const upb_EnumValueDef*)(v.val & ~kUpb_EnumDef_JsonOnlyTag);
+}
+
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) {
return (upb_EnumDef*)&e[i];
}
@@ -62,18 +84,43 @@ const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) {
return e->layout;
}
-bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) {
+void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e,
+ upb_EnumValueDef* v) {
const char* name = upb_EnumValueDef_Name(v);
const upb_value val = upb_value_constptr(v);
- bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a);
- if (!ok) return false;
+ bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, ctx->arena);
+ if (!ok) _upb_DefBuilder_OomErr(ctx);
- // Multiple enumerators can have the same number, first one wins.
+ // Aliased enum values can share the same custom JSON name, first one wins.
+ const char* json_name = upb_EnumValueDef_JsonName(v);
+ size_t json_len = strlen(json_name);
+ if (strcmp(json_name, name) != 0) {
+ upb_value existing_value;
+ if (upb_strtable_lookup2(&e->ntoi, json_name, json_len, &existing_value)) {
+ const upb_EnumValueDef* enumval = _upb_EnumDef_Untag(existing_value);
+ if (upb_EnumValueDef_Number(enumval) != upb_EnumValueDef_Number(v)) {
+ // If the custom JSON name exists, but points to a value with a
+ // different number, then this is a parse/conflict error.
+ _upb_DefBuilder_Errf(ctx,
+ "duplicate custom json_name (%s) in enum (%s)",
+ json_name, upb_EnumDef_FullName(e));
+ }
+ } else {
+ upb_value json_val = _upb_EnumDef_TagJsonOnly(val);
+ if (!upb_strtable_insert(&e->ntoi, json_name, json_len, json_val,
+ ctx->arena)) {
+ _upb_DefBuilder_OomErr(ctx);
+ }
+ }
+ }
+
+ // Multiple enum values can have the same number, first one wins.
const int number = upb_EnumValueDef_Number(v);
if (!upb_inttable_lookup(&e->iton, number, NULL)) {
- return upb_inttable_insert(&e->iton, number, val, a);
+ if (!upb_inttable_insert(&e->iton, number, val, ctx->arena)) {
+ _upb_DefBuilder_OomErr(ctx);
+ }
}
- return true;
}
const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) {
@@ -130,6 +177,16 @@ upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) {
int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; }
+const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(const upb_EnumDef* e,
+ const char* name,
+ size_t size) {
+ upb_value v;
+ if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) {
+ return NULL;
+ }
+ return _upb_EnumDef_Untag(v);
+}
+
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const char* name) {
return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name));
@@ -138,9 +195,13 @@ const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
const upb_EnumDef* e, const char* name, size_t size) {
upb_value v;
- return upb_strtable_lookup2(&e->ntoi, name, size, &v)
- ? upb_value_getconstptr(v)
- : NULL;
+ if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) {
+ return NULL;
+ }
+ if (_upb_EnumDef_IsJsonOnly(v)) {
+ return NULL;
+ }
+ return upb_value_getconstptr(v);
}
const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e,
@@ -281,7 +342,7 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix,
upb_EnumDef_FullName(e));
}
- bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena);
+ bool ok = upb_strtable_init(&e->ntoi, n_value * 2, ctx->arena);
if (!ok) _upb_DefBuilder_OomErr(ctx);
ok = upb_inttable_init(&e->iton, ctx->arena);
diff --git a/upb/reflection/enum_def.h b/upb/reflection/enum_def.h
index 3f81ba5d18..507b9557b7 100644
--- a/upb/reflection/enum_def.h
+++ b/upb/reflection/enum_def.h
@@ -12,6 +12,7 @@
#include
#include
+#include
#include "upb/base/string_view.h"
#include "upb/mem/arena.h"
@@ -29,6 +30,12 @@ bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num);
const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e);
int32_t upb_EnumDef_Default(const upb_EnumDef* e);
UPB_API const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e);
+UPB_API const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(
+ const upb_EnumDef* e, const char* name, size_t size);
+UPB_INLINE const upb_EnumValueDef* upb_EnumDef_FindByJsonName(
+ const upb_EnumDef* e, const char* name) {
+ return upb_EnumDef_FindByJsonNameWithSize(e, name, strlen(name));
+}
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e,
const char* name);
UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
diff --git a/upb/reflection/enum_value_def.c b/upb/reflection/enum_value_def.c
index 0e55288a15..69499d43f6 100644
--- a/upb/reflection/enum_value_def.c
+++ b/upb/reflection/enum_value_def.c
@@ -20,6 +20,8 @@
#include "upb/reflection/enum_value_def.h"
#include "upb/reflection/internal/def_builder.h"
#include "upb/reflection/internal/enum_def.h"
+#include "upb/reflection/internal/strdup2.h"
+#include "upb/reflection/json_enumvalue_options_bootstrap.h"
// Must be last.
#include "upb/port/def.inc"
@@ -29,6 +31,7 @@ struct upb_EnumValueDef {
const google_protobuf_FeatureSet* resolved_features;
const upb_EnumDef* parent;
const char* full_name;
+ const char* json_name;
int32_t number;
};
@@ -50,7 +53,7 @@ const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v,
(upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*));
if (!out) return NULL;
- for (int i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
out[i] = (upb_EnumValueDef*)&v[i];
}
qsort(out, n, sizeof(void*), _upb_EnumValueDef_Compare);
@@ -80,6 +83,10 @@ const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) {
return v->full_name;
}
+const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v) {
+ return v->json_name ? v->json_name : upb_EnumValueDef_Name(v);
+}
+
const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) {
return _upb_DefBuilder_FullToShort(v->full_name);
}
@@ -91,6 +98,19 @@ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) {
return v - upb_EnumDef_Value(v->parent, 0);
}
+static const char* _upb_EnumValueDef_ExtractJsonName(
+ upb_DefBuilder* ctx, const upb_EnumValueDef* v) {
+ if (!upb_EnumValueDef_HasOptions(v)) return NULL;
+ const google_protobuf_EnumValueOptions* opts = (const google_protobuf_EnumValueOptions*)v->opts;
+ if (!pb_enumvalue_has_json(opts)) return NULL;
+ const pb_enumvalue_JsonEnumValueOptions* json_opts = pb_enumvalue_json(opts);
+ if (!json_opts || !pb_enumvalue_JsonEnumValueOptions_has_string(json_opts)) {
+ return NULL;
+ }
+ upb_StringView str = pb_enumvalue_JsonEnumValueOptions_string(json_opts);
+ return upb_strdup2(str.data, str.size, ctx->arena);
+}
+
static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_EnumValueDescriptorProto* val_proto,
const google_protobuf_FeatureSet* parent_features,
@@ -105,11 +125,11 @@ static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix,
v->parent = e; // Must happen prior to _upb_DefBuilder_Add()
v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto);
+ v->json_name = _upb_EnumValueDef_ExtractJsonName(ctx, v);
_upb_DefBuilder_Add(ctx, v->full_name,
_upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL));
- bool ok = _upb_EnumDef_Insert(e, v, ctx->arena);
- if (!ok) _upb_DefBuilder_OomErr(ctx);
+ _upb_EnumDef_Insert(ctx, e, v);
}
// Allocate and initialize an array of |n| enum value defs owned by |e|.
diff --git a/upb/reflection/enum_value_def.h b/upb/reflection/enum_value_def.h
index a837236923..b3ab3ad975 100644
--- a/upb/reflection/enum_value_def.h
+++ b/upb/reflection/enum_value_def.h
@@ -10,6 +10,8 @@
#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_
#define UPB_REFLECTION_ENUM_VALUE_DEF_H_
+#include
+
#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"
@@ -24,6 +26,7 @@ const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v);
const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v);
bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v);
uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v);
+UPB_API const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v);
UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v);
UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v);
const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options(
diff --git a/upb/reflection/internal/enum_def.h b/upb/reflection/internal/enum_def.h
index c963000526..65fa07825e 100644
--- a/upb/reflection/internal/enum_def.h
+++ b/upb/reflection/internal/enum_def.h
@@ -21,7 +21,8 @@ extern "C" {
#endif
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i);
-bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a);
+void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e,
+ upb_EnumValueDef* v);
const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e);
// Allocate and initialize an array of |n| enum defs.
diff --git a/upb/reflection/json_enumvalue_options_bootstrap.h b/upb/reflection/json_enumvalue_options_bootstrap.h
new file mode 100644
index 0000000000..c6cefdf798
--- /dev/null
+++ b/upb/reflection/json_enumvalue_options_bootstrap.h
@@ -0,0 +1,19 @@
+#ifndef GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
+#define GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
+
+// IWYU pragma: begin_exports
+
+#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0
+// This header is checked in.
+#include "upb/reflection/stage0/google/protobuf/json_enumvalue_options.upb.h"
+#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 1
+// This header is generated at build time by the bootstrapping process.
+#include "upb/reflection/stage1/google/protobuf/json_enumvalue_options.upb.h"
+#else
+// This is the normal header, generated by upb_c_proto_library().
+#include "google/protobuf/json_enumvalue_options.upb.h"
+#endif
+
+// IWYU pragma: end_exports
+
+#endif // GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__
diff --git a/upb/reflection/reflection_test.cc b/upb/reflection/reflection_test.cc
index b64fd6b103..4dd55d4b4a 100644
--- a/upb/reflection/reflection_test.cc
+++ b/upb/reflection/reflection_test.cc
@@ -389,5 +389,77 @@ TEST(ReflectionTest, ZeroWeakDependencyIndexWithNoDeps) {
EXPECT_THAT(std::string(status.message()), HasSubstr("out of range"));
}
+// Sets (pb.enumvalue.json).string option (extension field 998) on
+// EnumValueOptions.
+static void SetCustomJsonOption(google::protobuf::EnumValueOptions* options,
+ absl::string_view json_name) {
+ // Wire format for JsonEnumValueOptions { string string = 1 }:
+ // Field 1 (string, length-delimited): tag = (1 << 3) | 2 = 0x0a.
+ std::string payload;
+ payload.push_back('\x0a');
+ payload.push_back(static_cast(json_name.size()));
+ payload.append(json_name);
+ // Field 998 is extension (pb.enumvalue.json) on EnumValueOptions.
+ options->mutable_unknown_fields()->AddLengthDelimited(998, payload);
+}
+
+struct TestEnumValueSpec {
+ std::string name;
+ int number;
+ std::string json_name;
+};
+
+static absl::StatusOr LoadEnumDescriptorWithValues(
+ absl::Span values) {
+ google::protobuf::FileDescriptorProto file_proto;
+ file_proto.set_name("test.proto");
+ file_proto.set_syntax("editions");
+ file_proto.set_edition(google::protobuf::EDITION_2026);
+
+ google::protobuf::EnumDescriptorProto* enum_proto = file_proto.add_enum_type();
+ enum_proto->set_name("TestEnum");
+
+ for (const TestEnumValueSpec& v : values) {
+ google::protobuf::EnumValueDescriptorProto* val_proto = enum_proto->add_value();
+ val_proto->set_name(v.name);
+ val_proto->set_number(v.number);
+ if (!v.json_name.empty()) {
+ SetCustomJsonOption(val_proto->mutable_options(), v.json_name);
+ }
+ }
+
+ google::protobuf::FileDescriptorSet set;
+ *set.add_file() = file_proto;
+ return LoadDescriptorSetFromProto(set);
+}
+
+TEST(ReflectionTest, EnumCustomJsonNameConflictDifferentNumberFails) {
+ // Two enum values with DIFFERENT numbers (1 and 2) sharing the same custom
+ // JSON name must fail descriptor validation.
+ absl::Status status =
+ LoadEnumDescriptorWithValues({
+ {"VAL_ZERO", 0, ""},
+ {"VAL_A", 1, "custom_name"},
+ {"VAL_B", 2, "custom_name"},
+ })
+ .status();
+ EXPECT_FALSE(status.ok());
+ EXPECT_THAT(std::string(status.message()),
+ HasSubstr("duplicate custom json_name (custom_name) in enum"));
+}
+
+TEST(ReflectionTest, EnumCustomJsonNameAliasedSameNumberSucceeds) {
+ // Two aliased enum values with the SAME number (1 and 1) sharing the same
+ // custom JSON name must succeed descriptor validation.
+ absl::Status status =
+ LoadEnumDescriptorWithValues({
+ {"VAL_ZERO", 0, ""},
+ {"VAL_A", 1, "custom_name"},
+ {"VAL_B", 1, "custom_name"},
+ })
+ .status();
+ EXPECT_TRUE(status.ok()) << status.message();
+}
+
} // namespace
} // namespace upb_test
diff --git a/upb/reflection/stage0/google/protobuf/descriptor.upb.c b/upb/reflection/stage0/google/protobuf/descriptor.upb.c
index 76a3b47ed5..efe2dd7977 100644
--- a/upb/reflection/stage0/google/protobuf/descriptor.upb.c
+++ b/upb/reflection/stage0/google/protobuf/descriptor.upb.c
@@ -2,13 +2,13 @@
#include "upb/generated_code_support.h"
#include "upb/reflection/descriptor_bootstrap.h"
-static upb_Arena* upb_BootstrapArena() {
+static upb_Arena* upb_BootstrapArena(void) {
static upb_Arena* arena = NULL;
if (!arena) arena = upb_Arena_New();
return arena;
}
-const upb_MiniTable* google__protobuf__FileDescriptorSet_msg_init() {
+const upb_MiniTable* google__protobuf__FileDescriptorSet_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$PG";
if (mini_table) return mini_table;
@@ -32,7 +32,7 @@ const upb_MiniTable* google__protobuf__FileDescriptorSet_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__FileDescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__FileDescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$11EGGGG33<<1a4E";
if (mini_table) return mini_table;
@@ -104,7 +104,7 @@ const upb_MiniTable* google__protobuf__FileDescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__DescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__DescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$1GGGGG3GGE4";
if (mini_table) return mini_table;
@@ -192,7 +192,7 @@ const upb_MiniTable* google__protobuf__DescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__DescriptorProto__ExtensionRange_msg_init() {
+const upb_MiniTable* google__protobuf__DescriptorProto__ExtensionRange_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$((3";
if (mini_table) return mini_table;
@@ -216,7 +216,7 @@ const upb_MiniTable* google__protobuf__DescriptorProto__ExtensionRange_msg_init(
return mini_table;
}
-const upb_MiniTable* google__protobuf__DescriptorProto__ReservedRange_msg_init() {
+const upb_MiniTable* google__protobuf__DescriptorProto__ReservedRange_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$((";
if (mini_table) return mini_table;
@@ -232,7 +232,7 @@ const upb_MiniTable* google__protobuf__DescriptorProto__ReservedRange_msg_init()
return mini_table;
}
-const upb_MiniTable* google__protobuf__ExtensionRangeOptions_msg_init() {
+const upb_MiniTable* google__protobuf__ExtensionRangeOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$PaG4n`3t|G";
if (mini_table) return mini_table;
@@ -280,7 +280,7 @@ const upb_MiniTable* google__protobuf__ExtensionRangeOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__ExtensionRangeOptions__Declaration_msg_init() {
+const upb_MiniTable* google__protobuf__ExtensionRangeOptions__Declaration_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$(11a//";
if (mini_table) return mini_table;
@@ -296,7 +296,7 @@ const upb_MiniTable* google__protobuf__ExtensionRangeOptions__Declaration_msg_in
return mini_table;
}
-const upb_MiniTable* google__protobuf__FieldDescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__FieldDescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$11(44113(1f/";
if (mini_table) return mini_table;
@@ -336,7 +336,7 @@ const upb_MiniTable* google__protobuf__FieldDescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__OneofDescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__OneofDescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$13";
if (mini_table) return mini_table;
@@ -360,7 +360,7 @@ const upb_MiniTable* google__protobuf__OneofDescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__EnumDescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__EnumDescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$1G3GE4";
if (mini_table) return mini_table;
@@ -408,7 +408,7 @@ const upb_MiniTable* google__protobuf__EnumDescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init() {
+const upb_MiniTable* google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$((";
if (mini_table) return mini_table;
@@ -424,7 +424,7 @@ const upb_MiniTable* google__protobuf__EnumDescriptorProto__EnumReservedRange_ms
return mini_table;
}
-const upb_MiniTable* google__protobuf__EnumValueDescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__EnumValueDescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$1(3";
if (mini_table) return mini_table;
@@ -448,7 +448,7 @@ const upb_MiniTable* google__protobuf__EnumValueDescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__ServiceDescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__ServiceDescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$1G3";
if (mini_table) return mini_table;
@@ -480,7 +480,7 @@ const upb_MiniTable* google__protobuf__ServiceDescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__MethodDescriptorProto_msg_init() {
+const upb_MiniTable* google__protobuf__MethodDescriptorProto_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$1113//";
if (mini_table) return mini_table;
@@ -504,7 +504,7 @@ const upb_MiniTable* google__protobuf__MethodDescriptorProto_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__FileOptions_msg_init() {
+const upb_MiniTable* google__protobuf__FileOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P1f14/1d///a/b/c/c/d11a111b11d3t|G";
if (mini_table) return mini_table;
@@ -544,7 +544,7 @@ const upb_MiniTable* google__protobuf__FileOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__MessageOptions_msg_init() {
+const upb_MiniTable* google__protobuf__MessageOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P///c/c/3z}G";
if (mini_table) return mini_table;
@@ -576,7 +576,7 @@ const upb_MiniTable* google__protobuf__MessageOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__FieldOptions_msg_init() {
+const upb_MiniTable* google__protobuf__FieldOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P4//a/4c/d//4aHG33p}G";
if (mini_table) return mini_table;
@@ -656,7 +656,7 @@ const upb_MiniTable* google__protobuf__FieldOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__FieldOptions__EditionDefault_msg_init() {
+const upb_MiniTable* google__protobuf__FieldOptions__EditionDefault_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$a14";
if (mini_table) return mini_table;
@@ -680,7 +680,7 @@ const upb_MiniTable* google__protobuf__FieldOptions__EditionDefault_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__FieldOptions__FeatureSupport_msg_init() {
+const upb_MiniTable* google__protobuf__FieldOptions__FeatureSupport_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$44141";
if (mini_table) return mini_table;
@@ -720,7 +720,7 @@ const upb_MiniTable* google__protobuf__FieldOptions__FeatureSupport_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__OneofOptions_msg_init() {
+const upb_MiniTable* google__protobuf__OneofOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P3e~G";
if (mini_table) return mini_table;
@@ -752,7 +752,7 @@ const upb_MiniTable* google__protobuf__OneofOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__EnumOptions_msg_init() {
+const upb_MiniTable* google__protobuf__EnumOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$Pa//b/3_~G";
if (mini_table) return mini_table;
@@ -784,7 +784,7 @@ const upb_MiniTable* google__protobuf__EnumOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__EnumValueOptions_msg_init() {
+const upb_MiniTable* google__protobuf__EnumValueOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P/3/3b~G";
if (mini_table) return mini_table;
@@ -824,7 +824,7 @@ const upb_MiniTable* google__protobuf__EnumValueOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__ServiceOptions_msg_init() {
+const upb_MiniTable* google__protobuf__ServiceOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P``/3d}G";
if (mini_table) return mini_table;
@@ -856,7 +856,7 @@ const upb_MiniTable* google__protobuf__ServiceOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__MethodOptions_msg_init() {
+const upb_MiniTable* google__protobuf__MethodOptions_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P``/43c}G";
if (mini_table) return mini_table;
@@ -896,7 +896,7 @@ const upb_MiniTable* google__protobuf__MethodOptions_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__UninterpretedOption_msg_init() {
+const upb_MiniTable* google__protobuf__UninterpretedOption_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$aG1,+ 01";
if (mini_table) return mini_table;
@@ -920,7 +920,7 @@ const upb_MiniTable* google__protobuf__UninterpretedOption_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__UninterpretedOption__NamePart_msg_init() {
+const upb_MiniTable* google__protobuf__UninterpretedOption__NamePart_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$1N/N";
if (mini_table) return mini_table;
@@ -936,7 +936,7 @@ const upb_MiniTable* google__protobuf__UninterpretedOption__NamePart_msg_init()
return mini_table;
}
-const upb_MiniTable* google__protobuf__FeatureSet_msg_init() {
+const upb_MiniTable* google__protobuf__FeatureSet_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$P444444444";
if (mini_table) return mini_table;
@@ -1024,7 +1024,7 @@ const upb_MiniTable* google__protobuf__FeatureSet_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__FeatureSet__VisibilityFeature_msg_init() {
+const upb_MiniTable* google__protobuf__FeatureSet__VisibilityFeature_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$";
if (mini_table) return mini_table;
@@ -1040,7 +1040,7 @@ const upb_MiniTable* google__protobuf__FeatureSet__VisibilityFeature_msg_init()
return mini_table;
}
-const upb_MiniTable* google__protobuf__FeatureSet__ProtoLimitsFeature_msg_init() {
+const upb_MiniTable* google__protobuf__FeatureSet__ProtoLimitsFeature_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$";
if (mini_table) return mini_table;
@@ -1056,7 +1056,7 @@ const upb_MiniTable* google__protobuf__FeatureSet__ProtoLimitsFeature_msg_init()
return mini_table;
}
-const upb_MiniTable* google__protobuf__FeatureSetDefaults_msg_init() {
+const upb_MiniTable* google__protobuf__FeatureSetDefaults_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$Gb44";
if (mini_table) return mini_table;
@@ -1096,7 +1096,7 @@ const upb_MiniTable* google__protobuf__FeatureSetDefaults_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init() {
+const upb_MiniTable* google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$b433";
if (mini_table) return mini_table;
@@ -1136,7 +1136,7 @@ const upb_MiniTable* google__protobuf__FeatureSetDefaults__FeatureSetEditionDefa
return mini_table;
}
-const upb_MiniTable* google__protobuf__SourceCodeInfo_msg_init() {
+const upb_MiniTable* google__protobuf__SourceCodeInfo_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$PG";
if (mini_table) return mini_table;
@@ -1160,7 +1160,7 @@ const upb_MiniTable* google__protobuf__SourceCodeInfo_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__SourceCodeInfo__Location_msg_init() {
+const upb_MiniTable* google__protobuf__SourceCodeInfo__Location_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$N<<11aE";
if (mini_table) return mini_table;
@@ -1176,7 +1176,7 @@ const upb_MiniTable* google__protobuf__SourceCodeInfo__Location_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__GeneratedCodeInfo_msg_init() {
+const upb_MiniTable* google__protobuf__GeneratedCodeInfo_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$G";
if (mini_table) return mini_table;
@@ -1200,7 +1200,7 @@ const upb_MiniTable* google__protobuf__GeneratedCodeInfo_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__GeneratedCodeInfo__Annotation_msg_init() {
+const upb_MiniTable* google__protobuf__GeneratedCodeInfo__Annotation_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$N<1((4";
if (mini_table) return mini_table;
@@ -1224,7 +1224,7 @@ const upb_MiniTable* google__protobuf__GeneratedCodeInfo__Annotation_msg_init()
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__Edition_enum_init() {
+const upb_MiniTableEnum* google__protobuf__Edition_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)~z!|aAcxg!h{va)|i}{~~`!";
if (mini_table) return mini_table;
@@ -1234,7 +1234,7 @@ const upb_MiniTableEnum* google__protobuf__Edition_enum_init() {
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__ExtensionRangeOptions__VerificationState_enum_init() {
+const upb_MiniTableEnum* google__protobuf__ExtensionRangeOptions__VerificationState_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!$";
if (mini_table) return mini_table;
@@ -1244,7 +1244,7 @@ const upb_MiniTableEnum* google__protobuf__ExtensionRangeOptions__VerificationSt
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__EnforceNamingStyle_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__EnforceNamingStyle_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!1";
if (mini_table) return mini_table;
@@ -1254,7 +1254,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__EnforceNamingStyle_enum_i
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__EnumType_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__EnumType_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1264,7 +1264,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__EnumType_enum_init() {
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__FieldPresence_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__FieldPresence_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!1";
if (mini_table) return mini_table;
@@ -1274,7 +1274,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__FieldPresence_enum_init()
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__JsonFormat_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__JsonFormat_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1284,7 +1284,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__JsonFormat_enum_init() {
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__MessageEncoding_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__MessageEncoding_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1294,7 +1294,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__MessageEncoding_enum_init
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__ProtoLimitsFeature__EnforceProtoLimits_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__ProtoLimitsFeature__EnforceProtoLimits_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1304,7 +1304,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__ProtoLimitsFeature__Enfor
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1314,7 +1314,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__RepeatedFieldEncoding_enu
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__Utf8Validation_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__Utf8Validation_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!/";
if (mini_table) return mini_table;
@@ -1324,7 +1324,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__Utf8Validation_enum_init(
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!A";
if (mini_table) return mini_table;
@@ -1334,7 +1334,7 @@ const upb_MiniTableEnum* google__protobuf__FeatureSet__VisibilityFeature__Defaul
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FieldDescriptorProto__Label_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FieldDescriptorProto__Label_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!0";
if (mini_table) return mini_table;
@@ -1344,7 +1344,7 @@ const upb_MiniTableEnum* google__protobuf__FieldDescriptorProto__Label_enum_init
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FieldDescriptorProto__Type_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FieldDescriptorProto__Type_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!@AA1";
if (mini_table) return mini_table;
@@ -1354,7 +1354,7 @@ const upb_MiniTableEnum* google__protobuf__FieldDescriptorProto__Type_enum_init(
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FieldOptions__CType_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FieldOptions__CType_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1364,7 +1364,7 @@ const upb_MiniTableEnum* google__protobuf__FieldOptions__CType_enum_init() {
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FieldOptions__JSType_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FieldOptions__JSType_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1374,7 +1374,7 @@ const upb_MiniTableEnum* google__protobuf__FieldOptions__JSType_enum_init() {
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FieldOptions__OptionRetention_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FieldOptions__OptionRetention_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1384,7 +1384,7 @@ const upb_MiniTableEnum* google__protobuf__FieldOptions__OptionRetention_enum_in
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FieldOptions__OptionTargetType_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FieldOptions__OptionTargetType_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!AA";
if (mini_table) return mini_table;
@@ -1394,7 +1394,7 @@ const upb_MiniTableEnum* google__protobuf__FieldOptions__OptionTargetType_enum_i
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__FileOptions__OptimizeMode_enum_init() {
+const upb_MiniTableEnum* google__protobuf__FileOptions__OptimizeMode_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!0";
if (mini_table) return mini_table;
@@ -1404,7 +1404,7 @@ const upb_MiniTableEnum* google__protobuf__FileOptions__OptimizeMode_enum_init()
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init() {
+const upb_MiniTableEnum* google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1414,7 +1414,7 @@ const upb_MiniTableEnum* google__protobuf__GeneratedCodeInfo__Annotation__Semant
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__MethodOptions__IdempotencyLevel_enum_init() {
+const upb_MiniTableEnum* google__protobuf__MethodOptions__IdempotencyLevel_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
@@ -1424,7 +1424,7 @@ const upb_MiniTableEnum* google__protobuf__MethodOptions__IdempotencyLevel_enum_
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__SymbolVisibility_enum_init() {
+const upb_MiniTableEnum* google__protobuf__SymbolVisibility_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
diff --git a/upb/reflection/stage0/google/protobuf/json_enumvalue_options.upb.c b/upb/reflection/stage0/google/protobuf/json_enumvalue_options.upb.c
new file mode 100644
index 0000000000..685b6cf820
--- /dev/null
+++ b/upb/reflection/stage0/google/protobuf/json_enumvalue_options.upb.c
@@ -0,0 +1,27 @@
+#include
+#include "upb/generated_code_support.h"
+#include "upb/reflection/json_enumvalue_options_bootstrap.h"
+
+#include "upb/reflection/descriptor_bootstrap.h"
+static upb_Arena* upb_BootstrapArena(void) {
+ static upb_Arena* arena = NULL;
+ if (!arena) arena = upb_Arena_New();
+ return arena;
+}
+
+const upb_MiniTable* pb__enumvalue__JsonEnumValueOptions_msg_init(void) {
+ static upb_MiniTable* mini_table = NULL;
+ static const char* mini_descriptor = "$M1";
+ if (mini_table) return mini_table;
+ upb_Status status;
+ mini_table =
+ upb_MiniTable_Build(mini_descriptor, strlen(mini_descriptor),
+ upb_BootstrapArena(), &status);
+ if (!mini_table) {
+ fprintf(stderr, "Failed to build mini_table for pb__enumvalue__JsonEnumValueOptions_msg_init: %s\n",
+ upb_Status_ErrorMessage(&status));
+ abort();
+ }
+ return mini_table;
+}
+
diff --git a/upb/reflection/stage0/google/protobuf/json_enumvalue_options.upb.h b/upb/reflection/stage0/google/protobuf/json_enumvalue_options.upb.h
new file mode 100644
index 0000000000..f2a7c7aa47
--- /dev/null
+++ b/upb/reflection/stage0/google/protobuf/json_enumvalue_options.upb.h
@@ -0,0 +1,122 @@
+/* This file was generated by upb_generator from the input file:
+ *
+ * google/protobuf/json_enumvalue_options.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated.
+ * NO CHECKED-IN PROTOBUF GENCODE */
+
+#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_
+
+#include "upb/generated_code_support.h"
+// Must be last.
+#include "upb/port/def.inc"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern const upb_MiniTable* pb__enumvalue__JsonEnumValueOptions_msg_init(void);
+extern const upb_MiniTable* google__protobuf__EnumValueOptions_msg_init(void);
+
+typedef struct pb_enumvalue_JsonEnumValueOptions {
+ upb_Message UPB_PRIVATE(base);
+} pb_enumvalue_JsonEnumValueOptions;
+
+struct google_protobuf_EnumValueOptions;
+
+
+
+/* pb.enumvalue.JsonEnumValueOptions */
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_new(upb_Arena* arena) {
+ return (pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(pb__enumvalue__JsonEnumValueOptions_msg_init(), arena);
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse(const char* buf, size_t size,
+ upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), pb__enumvalue__JsonEnumValueOptions_msg_init(), NULL, 0,
+ arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse_ex(
+ const char* buf, size_t size, const upb_ExtensionRegistry* extreg,
+ int options, upb_Arena* arena) {
+ pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena);
+ if (!ret) return NULL;
+ if (upb_Decode(buf, size, UPB_UPCAST(ret), pb__enumvalue__JsonEnumValueOptions_msg_init(), extreg,
+ options, arena) != kUpb_DecodeStatus_Ok) {
+ return NULL;
+ }
+ return ret;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize(const pb_enumvalue_JsonEnumValueOptions* msg,
+ upb_Arena* arena, size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), pb__enumvalue__JsonEnumValueOptions_msg_init(), 0, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize_ex(const pb_enumvalue_JsonEnumValueOptions* msg,
+ int options, upb_Arena* arena,
+ size_t* len) {
+ char* ptr;
+ (void)upb_Encode(UPB_UPCAST(msg), pb__enumvalue__JsonEnumValueOptions_msg_init(), options, arena, &ptr, len);
+ return ptr;
+}
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_clear_string(pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = *upb_MiniTable_FindFieldByNumber(pb__enumvalue__JsonEnumValueOptions_msg_init(), 1);
+ upb_Message_ClearBaseField(UPB_UPCAST(msg), &field);
+}
+UPB_INLINE upb_StringView pb_enumvalue_JsonEnumValueOptions_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ upb_StringView default_val = upb_StringView_FromString("");
+ upb_StringView ret;
+ const upb_MiniTableField field = *upb_MiniTable_FindFieldByNumber(pb__enumvalue__JsonEnumValueOptions_msg_init(), 1);
+ _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field,
+ &default_val, &ret);
+ return ret;
+}
+UPB_INLINE bool pb_enumvalue_JsonEnumValueOptions_has_string(const pb_enumvalue_JsonEnumValueOptions* msg) {
+ const upb_MiniTableField field = *upb_MiniTable_FindFieldByNumber(pb__enumvalue__JsonEnumValueOptions_msg_init(), 1);
+ return upb_Message_HasBaseField(UPB_UPCAST(msg), &field);
+}
+
+UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_set_string(pb_enumvalue_JsonEnumValueOptions* msg, upb_StringView value) {
+ const upb_MiniTableField field = *upb_MiniTable_FindFieldByNumber(pb__enumvalue__JsonEnumValueOptions_msg_init(), 1);
+ upb_Message_SetBaseField((upb_Message*)msg, &field, &value);
+}
+
+// In stage0 bootstrapping, extensions are not present.
+UPB_INLINE bool pb_enumvalue_has_json(const struct google_protobuf_EnumValueOptions* msg) {
+ (void)msg;
+ return false;
+}
+
+UPB_INLINE void pb_enumvalue_clear_json(struct google_protobuf_EnumValueOptions* msg) { (void)msg; }
+UPB_INLINE const pb_enumvalue_JsonEnumValueOptions*
+pb_enumvalue_json(const struct google_protobuf_EnumValueOptions* msg) {
+ (void)msg;
+ return NULL;
+}
+
+UPB_INLINE void pb_enumvalue_set_json(struct google_protobuf_EnumValueOptions* msg,
+ const pb_enumvalue_JsonEnumValueOptions* val,
+ upb_Arena* arena) {
+ (void)msg;
+ (void)val;
+ (void)arena;
+}
+UPB_INLINE struct pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_mutable_json(
+ struct google_protobuf_EnumValueOptions* msg, upb_Arena* arena) {
+ (void)msg;
+ (void)arena;
+ return NULL;
+}
+#ifdef __cplusplus
+ } /* extern "C" */
+#endif
+
+#include "upb/port/undef.inc"
+
+#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ */
diff --git a/upb_generator/bootstrap_compiler.bzl b/upb_generator/bootstrap_compiler.bzl
index 4e8c53c74b..93dee5b535 100644
--- a/upb_generator/bootstrap_compiler.bzl
+++ b/upb_generator/bootstrap_compiler.bzl
@@ -2,6 +2,10 @@
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
load("@rules_cc//cc:defs.bzl", "cc_library")
+load(
+ "//upb/bazel:copts.bzl",
+ "UPB_DEFAULT_COPTS",
+)
load(
"//upb/bazel:upb_minitable_proto_library.bzl",
"upb_minitable_proto_library",
@@ -15,6 +19,11 @@ load(
"staleness_test",
)
+def _c_library_with_default_copts(**kwargs):
+ cc_kwargs = dict(kwargs)
+ cc_kwargs["copts"] = UPB_DEFAULT_COPTS + cc_kwargs.get("copts", [])
+ cc_library(**cc_kwargs)
+
_stages = ["_stage0", "_stage1", ""]
_protoc = "//src/google/protobuf/compiler/release:protoc_minimal"
@@ -105,11 +114,11 @@ def _generated_hdrs_and_srcs(protos, stage, generator):
ret += _generated_files(protos, stage, generator, "c")
return ret
-def _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix):
+def _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix, third_party_dir = "3rd_party"):
native.genrule(
name = name + "_generate_bootstrap",
srcs = src_rules,
- outs = ["bootstrap_generated_sources/" + f.replace("third_party", "3rd_party") for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")],
+ outs = ["bootstrap_generated_sources/" + f.replace("third_party", third_party_dir) for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")],
tools = [_protoc, _upbc("upb", 0)],
cmd =
"$(location " + _protoc + ") " +
@@ -117,15 +126,18 @@ def _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix):
"--plugin=protoc-gen-upb=$(location " + _upbc("upb", 0) + ") " +
"--upb_out=bootstrap_stage=0:$(@D)/bootstrap_generated_sources/stage0 " +
" ".join(src_files) +
- "; rm -rf $(@D)/bootstrap_generated_sources/stage0/3rd_party" +
- "; if [ -e $(@D)/bootstrap_generated_sources/stage0/third_party ]; then mv $(@D)/bootstrap_generated_sources/stage0/third_party $(@D)/bootstrap_generated_sources/stage0/3rd_party; fi",
+ "; rm -rf $(@D)/bootstrap_generated_sources/stage0/" + third_party_dir +
+ "; if [ -e $(@D)/bootstrap_generated_sources/stage0/third_party ]; then mv $(@D)/bootstrap_generated_sources/stage0/third_party $(@D)/bootstrap_generated_sources/stage0/" + third_party_dir + "; fi",
)
staleness_test(
name = name + "_stage0_staleness_test",
- outs = [f.replace("third_party", "3rd_party") for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")],
+ outs = [f.replace("third_party", third_party_dir) for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")],
generated_pattern = "bootstrap_generated_sources/%s",
- target_files = native.glob(["stage0/**"]),
+ target_files = [
+ f.replace("third_party", third_party_dir)
+ for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")
+ ],
# To avoid skew problems for descriptor.proto/plugin.proto between
# GitHub repos. It's not critical that the checked-in protos are up to
# date for every change, they just needs to be complete enough to have
@@ -194,6 +206,7 @@ def bootstrap_upb_proto_library(
proto_lib_deps,
deps = [],
strip_prefix = "",
+ third_party_dir = "3rd_party",
**kwargs):
"""A version of upb_proto_library() that is augmented to allow for bootstrapping the compiler.
@@ -211,13 +224,15 @@ def bootstrap_upb_proto_library(
not bootstrapping.
deps: other bootstrap_upb_proto_library() rules that this one depends on.
strip_prefix: Prefix that should be stripped from file names.
+ third_party_dir: Subdirectory name to use instead of "third_party" for stage0 checked-in
+ files to comply with repository structure rules.
**kwargs: Other arguments that will be passed through to cc_library(), genrule(), and
upb_proto_library().
"""
- _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix)
+ _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix, third_party_dir)
# stage0 uses checked-in protos, and has no MiniTable.
- cc_library(
+ _c_library_with_default_copts(
name = name + "_stage0",
srcs = _generated_hdrs_and_srcs(src_files, "stage0", "upb"),
hdrs = [bootstrap_hdr],
@@ -233,7 +248,7 @@ def bootstrap_upb_proto_library(
# Generate stage1 protos (C API and MiniTables) using stage0 compiler.
_generate_stage1_proto(name, src_files, src_rules, "upb", kwargs)
_generate_stage1_proto(name, src_files, src_rules, "upb_minitable", kwargs)
- cc_library(
+ _c_library_with_default_copts(
name = name + "_minitable_stage1",
srcs = _generated_files(src_files, "stage1", "upb_minitable", "c"),
hdrs = _generated_files(src_files, "stage1", "upb_minitable", "h"),
@@ -244,7 +259,7 @@ def bootstrap_upb_proto_library(
] + [dep + "_minitable_stage1" for dep in deps],
**kwargs
)
- cc_library(
+ _c_library_with_default_copts(
name = name + "_stage1",
srcs = _generated_files(src_files, "stage1", "upb", "h"),
hdrs = [bootstrap_hdr],
@@ -263,7 +278,7 @@ def bootstrap_upb_proto_library(
deps = proto_lib_deps,
**kwargs
)
- cc_library(
+ _c_library_with_default_copts(
name = name,
hdrs = [bootstrap_hdr],
deps = [name + "_upb_proto"],
diff --git a/upb_generator/c/generator.cc b/upb_generator/c/generator.cc
index bafa181270..5c2caf4ce8 100644
--- a/upb_generator/c/generator.cc
+++ b/upb_generator/c/generator.cc
@@ -313,6 +313,72 @@ std::string GetFieldRep(const DefPoolPair& pools, upb::FieldDefPtr field) {
}
void GenerateExtensionInHeader(Context& c, upb::FieldDefPtr ext) {
+ if (c.options().bootstrap_stage == 0) {
+ c.Emit(
+ {
+ {"ident_base", ExtensionIdentBase(ext)},
+ {"name", ext.name()},
+ {"ctype", MessageType(ext.containing_type())},
+ },
+ R"cc(
+ // In stage0 bootstrapping, extensions are not present.
+ UPB_INLINE bool $ident_base$_has_$name$(const struct $ctype$* msg) {
+ (void)msg;
+ return false;
+ }
+
+ UPB_INLINE void $ident_base$_clear_$name$(struct $ctype$* msg) { (void)msg; }
+ )cc");
+
+ if (ext.IsSequence()) {
+ // Repeated extensions are accessed via generic upb_Array and
+ // upb_Message_GetExtension APIs.
+ } else {
+ c.Emit(
+ {
+ {"ctype_const", CTypeConst(ext)},
+ {"ident_base", ExtensionIdentBase(ext)},
+ {"name", ext.name()},
+ {"ctype", MessageType(ext.containing_type())},
+ {"default", FieldDefault(ext)},
+ },
+ R"cc(
+ UPB_INLINE $ctype_const$
+ $ident_base$_$name$(const struct $ctype$* msg) {
+ (void)msg;
+ return $default$;
+ }
+
+ UPB_INLINE void $ident_base$_set_$name$(struct $ctype$* msg,
+ $ctype_const$ val,
+ upb_Arena* arena) {
+ (void)msg;
+ (void)val;
+ (void)arena;
+ }
+ )cc");
+
+ if (ext.IsSubMessage()) {
+ c.Emit(
+ {
+ {"sub_ctype", MessageType(ext.message_type())},
+ {"ident_base", ExtensionIdentBase(ext)},
+ {"name", ext.name()},
+ {"ctype", MessageType(ext.containing_type())},
+ },
+ R"cc(
+ UPB_INLINE struct $sub_ctype$* $ident_base$_mutable_$name$(
+ struct $ctype$* msg, upb_Arena* arena) {
+ (void)msg;
+ (void)arena;
+ return NULL;
+ }
+ )cc");
+ }
+ }
+ return;
+ }
+
c.Emit(
{
{"ident_base", ExtensionIdentBase(ext)},
@@ -331,7 +397,8 @@ void GenerateExtensionInHeader(Context& c, upb::FieldDefPtr ext) {
)cc");
if (ext.IsSequence()) {
- // TODO: We need generated accessors for repeated extensions.
+ // Repeated extensions are accessed via generic upb_Array and
+ // upb_Message_GetExtension APIs.
} else {
c.Emit(
{
@@ -1206,7 +1273,7 @@ void WriteMessageMiniDescriptorInitializer(Context& c, upb::MessageDefPtr msg) {
{"mini_descriptor", msg.MiniDescriptorEncode()},
{"resolve_calls", [&] { WriteResolveCalls(c, msg); }}},
R"cc(
- const upb_MiniTable* $name$() {
+ const upb_MiniTable* $name$(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$mini_descriptor$";
if (mini_table) return mini_table;
@@ -1229,7 +1296,7 @@ void WriteEnumMiniDescriptorInitializer(Context& c, upb::EnumDefPtr enum_def) {
c.Emit({{"name", MiniTableEnumVarName(enum_def.full_name())},
{"mini_descriptor", enum_def.MiniDescriptorEncode()}},
R"cc(
- const upb_MiniTableEnum* $name$() {
+ const upb_MiniTableEnum* $name$(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "$mini_descriptor$";
if (mini_table) return mini_table;
@@ -1262,7 +1329,7 @@ void WriteMiniDescriptorSource(Context& c, upb::FileDefPtr file) {
c.Emit(
R"cc(
- static upb_Arena* upb_BootstrapArena() {
+ static upb_Arena* upb_BootstrapArena(void) {
static upb_Arena* arena = NULL;
if (!arena) arena = upb_Arena_New();
return arena;
diff --git a/upb_generator/c/names_internal.cc b/upb_generator/c/names_internal.cc
index b2f29d4401..38f346b558 100644
--- a/upb_generator/c/names_internal.cc
+++ b/upb_generator/c/names_internal.cc
@@ -18,7 +18,14 @@ namespace generator {
std::string CApiHeaderFilename(absl::string_view proto_filename,
bool bootstrap) {
if (bootstrap) {
- if (IsDescriptorProto(proto_filename)) {
+ if (proto_filename == "third_party/protobuf/json_enumvalue_options.proto" ||
+ proto_filename == "google/protobuf/json_enumvalue_options.proto" ||
+ proto_filename == "src/google/protobuf/json_enumvalue_options.proto") {
+ return "upb/reflection/"
+ "json_enumvalue_options_bootstrap.h";
+ } else if (proto_filename == "net/proto2/proto/descriptor.proto" ||
+ proto_filename == "google/protobuf/descriptor.proto" ||
+ proto_filename == "src/google/protobuf/descriptor.proto") {
return "upb/reflection/descriptor_bootstrap.h";
} else {
return "upb_generator/plugin_bootstrap.h";
diff --git a/upb_generator/cmake/google/protobuf/compiler/plugin.upb_minitable.c b/upb_generator/cmake/google/protobuf/compiler/plugin.upb_minitable.c
index 1cf1dc4894..2a144a43e0 100644
--- a/upb_generator/cmake/google/protobuf/compiler/plugin.upb_minitable.c
+++ b/upb_generator/cmake/google/protobuf/compiler/plugin.upb_minitable.c
@@ -212,20 +212,20 @@ const upb_MiniTableEnum google__protobuf__compiler__CodeGeneratorResponse__Featu
},
};
-static const upb_MiniTable *messages_layout[4] = {
+static const upb_MiniTable *messages_layout_google_protobuf_compiler_plugin_proto_upb_file_layout[4] = {
&google__protobuf__compiler__Version_msg_init,
&google__protobuf__compiler__CodeGeneratorRequest_msg_init,
&google__protobuf__compiler__CodeGeneratorResponse_msg_init,
&google__protobuf__compiler__CodeGeneratorResponse__File_msg_init,
};
-static const upb_MiniTableEnum *enums_layout[1] = {
+static const upb_MiniTableEnum *enums_layout_google_protobuf_compiler_plugin_proto_upb_file_layout[1] = {
&google__protobuf__compiler__CodeGeneratorResponse__Feature_enum_init,
};
const upb_MiniTableFile google_protobuf_compiler_plugin_proto_upb_file_layout = {
- messages_layout,
- enums_layout,
+ messages_layout_google_protobuf_compiler_plugin_proto_upb_file_layout,
+ enums_layout_google_protobuf_compiler_plugin_proto_upb_file_layout,
NULL,
4,
1,
diff --git a/upb_generator/common/names.cc b/upb_generator/common/names.cc
index 8cec63fdbe..63e47a0865 100644
--- a/upb_generator/common/names.cc
+++ b/upb_generator/common/names.cc
@@ -31,9 +31,13 @@ std::string ToPreproc(absl::string_view str) {
} // namespace
-bool IsDescriptorProto(absl::string_view filename) {
+bool IsReflectionBootstrapProto(absl::string_view filename) {
return filename == "net/proto2/proto/descriptor.proto" ||
- filename == "google/protobuf/descriptor.proto";
+ filename == "google/protobuf/descriptor.proto" ||
+ filename == "src/google/protobuf/descriptor.proto" ||
+ filename == "third_party/protobuf/json_enumvalue_options.proto" ||
+ filename == "google/protobuf/json_enumvalue_options.proto" ||
+ filename == "src/google/protobuf/json_enumvalue_options.proto";
}
std::string StripExtension(absl::string_view fname) {
diff --git a/upb_generator/common/names.h b/upb_generator/common/names.h
index 793b5d2cf1..78a2411210 100644
--- a/upb_generator/common/names.h
+++ b/upb_generator/common/names.h
@@ -18,7 +18,7 @@
namespace upb {
namespace generator {
-bool IsDescriptorProto(absl::string_view filename);
+bool IsReflectionBootstrapProto(absl::string_view filename);
std::string StripExtension(absl::string_view fname);
std::string IncludeGuard(absl::string_view filename);
std::string FileWarning(absl::string_view filename);
diff --git a/upb_generator/minitable/generator.cc b/upb_generator/minitable/generator.cc
index 54f8490ce4..c074e724e1 100644
--- a/upb_generator/minitable/generator.cc
+++ b/upb_generator/minitable/generator.cc
@@ -309,7 +309,7 @@ void WriteExtension(const DefPoolPair& pools, upb::FieldDefPtr ext,
void RegisterExtensions(Output& output, absl::string_view unique_name) {
output("UPB_LINKARR_DECLARE(upb_AllExts, const upb_MiniTableExtension*);\n");
- output("UPB_CONSTRUCTOR(upb_GeneratedRegistry_Constructor, $0) {\n",
+ output("UPB_CONSTRUCTOR(upb_GeneratedRegistry_Constructor, $0, {\n",
unique_name);
// TODO Although we define this function as weak and only one
// copy will ever exist in any binary, every instance will get registered as a
@@ -326,7 +326,7 @@ void RegisterExtensions(Output& output, absl::string_view unique_name) {
output(" UPB_ASSERT(entry.next == NULL);\n");
output(" entry.next = UPB_PRIVATE(upb_generated_extension_list);\n");
output(" UPB_PRIVATE(upb_generated_extension_list) = &entry;\n");
- output("}\n");
+ output("})\n");
}
} // namespace
@@ -458,9 +458,15 @@ void WriteMiniTableSource(const DefPoolPair& pools, upb::FileDefPtr file,
}
}
+ std::string messages_layout =
+ absl::StrCat("messages_layout_", FileVarName(file));
+ std::string enums_layout = absl::StrCat("enums_layout_", FileVarName(file));
+ std::string extensions_layout =
+ absl::StrCat("extensions_layout_", FileVarName(file));
+
// Messages.
if (!messages.empty()) {
- output("static const upb_MiniTable *$0[$1] = {\n", kMessagesInit,
+ output("static const upb_MiniTable *$0[$1] = {\n", messages_layout,
messages.size());
for (auto message : messages) {
output(" &$0,\n", MessageVarName(message));
@@ -471,7 +477,7 @@ void WriteMiniTableSource(const DefPoolPair& pools, upb::FileDefPtr file,
// Enums.
if (!enums.empty()) {
- output("static const upb_MiniTableEnum *$0[$1] = {\n", kEnumsInit,
+ output("static const upb_MiniTableEnum *$0[$1] = {\n", enums_layout,
enums.size());
for (const auto e : enums) {
output(" &$0,\n", EnumVarName(e));
@@ -485,7 +491,7 @@ void WriteMiniTableSource(const DefPoolPair& pools, upb::FileDefPtr file,
output(
"\n"
"static const upb_MiniTableExtension *$0[$1] = {\n",
- kExtensionsInit, extensions.size());
+ extensions_layout, extensions.size());
for (auto ext : extensions) {
output(" &$0_obj,\n", ExtensionVarName(ext));
@@ -503,9 +509,9 @@ void WriteMiniTableSource(const DefPoolPair& pools, upb::FileDefPtr file,
}
output("const upb_MiniTableFile $0 = {\n", FileVarName(file));
- output(" $0,\n", messages.empty() ? "NULL" : kMessagesInit);
- output(" $0,\n", enums.empty() ? "NULL" : kEnumsInit);
- output(" $0,\n", extensions.empty() ? "NULL" : kExtensionsInit);
+ output(" $0,\n", messages.empty() ? "NULL" : messages_layout);
+ output(" $0,\n", enums.empty() ? "NULL" : enums_layout);
+ output(" $0,\n", extensions.empty() ? "NULL" : extensions_layout);
output(" $0,\n", messages.size());
output(" $0,\n", enums.size());
output(" $0,\n", extensions.size());
diff --git a/upb_generator/minitable/names_internal.cc b/upb_generator/minitable/names_internal.cc
index 86058f6fbf..390a40e0c0 100644
--- a/upb_generator/minitable/names_internal.cc
+++ b/upb_generator/minitable/names_internal.cc
@@ -28,7 +28,7 @@ std::string MiniTableHeaderFilename(absl::string_view proto_filename,
bool bootstrap) {
std::string base;
if (bootstrap) {
- if (IsDescriptorProto(proto_filename)) {
+ if (IsReflectionBootstrapProto(proto_filename)) {
base = "upb/reflection/stage1/";
} else {
base = "upb_generator/stage1/";
diff --git a/upb_generator/reflection/source.cc b/upb_generator/reflection/source.cc
index a573f1f575..6cca2370bc 100644
--- a/upb_generator/reflection/source.cc
+++ b/upb_generator/reflection/source.cc
@@ -89,13 +89,15 @@ void WriteDescriptor(upb::FileDefPtr file, Context& ctx) {
file_proto, arena.ptr(), &serialized_size);
absl::string_view file_data(serialized, serialized_size);
- ctx.Emit({{"serialized_size", file_data.size()},
- {"contents", [&] { WriteStringArray(file_data, ctx); }}},
- R"cc(
- static const char descriptor[$serialized_size$] = {
- $contents$,
- };
- )cc");
+ ctx.Emit(
+ {{"serialized_size", file_data.size()},
+ {"defpool_init_name", ReflectionFileSymbol(file.name())},
+ {"contents", [&] { WriteStringArray(file_data, ctx); }}},
+ R"cc(
+ static const char descriptor_$defpool_init_name$[$serialized_size$] = {
+ $contents$,
+ };
+ )cc");
ctx.Emit("\n");
}
@@ -112,9 +114,10 @@ void WriteDependencies(upb::FileDefPtr file, Context& ctx) {
};
ctx.Emit({{"dep_count", file.dependency_count() + 1},
+ {"defpool_init_name", ReflectionFileSymbol(file.name())},
{google::protobuf::io::Printer::Sub("deps", write_deps).WithSuffix(",")}},
R"cc(
- static _upb_DefPool_Init *deps[$dep_count$] = {
+ static _upb_DefPool_Init* deps_$defpool_init_name$[$dep_count$] = {
$deps$,
NULL,
};
@@ -131,10 +134,11 @@ void WriteDefPoolInitStruct(upb::FileDefPtr file, Context& ctx) {
},
R"cc(
_upb_DefPool_Init $defpool_init_name$ = {
- deps,
+ deps_$defpool_init_name$,
&$mini_table_file_var_name$,
"$file_name$",
- UPB_STRINGVIEW_INIT(descriptor, sizeof(descriptor)),
+ UPB_STRINGVIEW_INIT(descriptor_$defpool_init_name$,
+ sizeof(descriptor_$defpool_init_name$)),
};
)cc");
}
diff --git a/upb_generator/stage0/google/protobuf/compiler/plugin.upb.c b/upb_generator/stage0/google/protobuf/compiler/plugin.upb.c
index f3996fb8fb..9d8e3837c3 100644
--- a/upb_generator/stage0/google/protobuf/compiler/plugin.upb.c
+++ b/upb_generator/stage0/google/protobuf/compiler/plugin.upb.c
@@ -3,13 +3,13 @@
#include "upb_generator/plugin_bootstrap.h"
#include "upb/reflection/descriptor_bootstrap.h"
-static upb_Arena* upb_BootstrapArena() {
+static upb_Arena* upb_BootstrapArena(void) {
static upb_Arena* arena = NULL;
if (!arena) arena = upb_Arena_New();
return arena;
}
-const upb_MiniTable* google__protobuf__compiler__Version_msg_init() {
+const upb_MiniTable* google__protobuf__compiler__Version_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$(((1";
if (mini_table) return mini_table;
@@ -25,7 +25,7 @@ const upb_MiniTable* google__protobuf__compiler__Version_msg_init() {
return mini_table;
}
-const upb_MiniTable* google__protobuf__compiler__CodeGeneratorRequest_msg_init() {
+const upb_MiniTable* google__protobuf__compiler__CodeGeneratorRequest_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$E13kGaG";
if (mini_table) return mini_table;
@@ -65,7 +65,7 @@ const upb_MiniTable* google__protobuf__compiler__CodeGeneratorRequest_msg_init()
return mini_table;
}
-const upb_MiniTable* google__protobuf__compiler__CodeGeneratorResponse_msg_init() {
+const upb_MiniTable* google__protobuf__compiler__CodeGeneratorResponse_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$1,((jG";
if (mini_table) return mini_table;
@@ -89,7 +89,7 @@ const upb_MiniTable* google__protobuf__compiler__CodeGeneratorResponse_msg_init(
return mini_table;
}
-const upb_MiniTable* google__protobuf__compiler__CodeGeneratorResponse__File_msg_init() {
+const upb_MiniTable* google__protobuf__compiler__CodeGeneratorResponse__File_msg_init(void) {
static upb_MiniTable* mini_table = NULL;
static const char* mini_descriptor = "$11l13";
if (mini_table) return mini_table;
@@ -113,7 +113,7 @@ const upb_MiniTable* google__protobuf__compiler__CodeGeneratorResponse__File_msg
return mini_table;
}
-const upb_MiniTableEnum* google__protobuf__compiler__CodeGeneratorResponse__Feature_enum_init() {
+const upb_MiniTableEnum* google__protobuf__compiler__CodeGeneratorResponse__Feature_enum_init(void) {
static const upb_MiniTableEnum* mini_table = NULL;
static const char* mini_descriptor = "!)";
if (mini_table) return mini_table;
diff --git a/version.json b/version.json
index 2c48cb3842..db9ab44a1f 100644
--- a/version.json
+++ b/version.json
@@ -1,18 +1,18 @@
{
- "main": {
- "protoc_version": "36-dev",
+ "36.x": {
+ "protoc_version": "36.0-rc2",
"lts": false,
- "date": "2026-04-15",
+ "date": "2026-08-03",
"languages": {
- "cpp": "7.36-dev",
- "csharp": "3.36-dev",
- "java": "4.36-dev",
- "javascript": "3.36-dev",
- "objectivec": "5.36-dev",
- "php": "5.36-dev",
- "python": "7.36-dev",
- "ruby": "4.36-dev",
- "rust": "4.36-dev"
+ "cpp": "7.36.0-rc2",
+ "csharp": "3.36.0-rc2",
+ "java": "4.36.0-rc2",
+ "javascript": "3.36.0-rc2",
+ "objectivec": "5.36.0-rc2",
+ "php": "5.36.0-rc2",
+ "python": "7.36.0-rc2",
+ "ruby": "4.36.0-rc2",
+ "rust": "4.36.0-rc2"
}
}
}
\ No newline at end of file