Merge tag 'refs/tags/sync-piper' into sync-stage

# Conflicts:
#	build_defs/cpp_opts.bzl
pull/10797/head
Mike Kruskal 2 years ago
commit 1a238479d8
  1. 34
      .bazelrc
  2. 1
      CMakeLists.txt
  3. 25
      build_defs/cpp_opts.bzl
  4. 3
      cmake/libprotobuf-lite.cmake
  5. 3
      cmake/libprotobuf.cmake
  6. 12
      cmake/utf8_range.cmake
  7. 3
      conformance/BUILD.bazel
  8. 3
      java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
  9. 3
      java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java
  10. 22
      java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java
  11. 2
      java/core/src/test/proto/com/google/protobuf/map_for_proto2_lite_test.proto
  12. 5
      java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto
  13. 9
      java/kotlin-lite/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt
  14. 16
      java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt
  15. 8
      java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt
  16. 8
      java/kotlin/src/main/kotlin/com/google/protobuf/DslMap.kt
  17. 6
      java/kotlin/src/main/kotlin/com/google/protobuf/DslProxy.kt
  18. 13
      java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt
  19. 4
      java/kotlin/src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt
  20. 4
      java/kotlin/src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt
  21. 19
      java/kotlin/src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt
  22. 16
      java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt
  23. 35
      java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt
  24. 16
      java/kotlin/src/test/kotlin/com/google/protobuf/ExtendableMessageExtensionsTest.kt
  25. 74
      java/kotlin/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt
  26. 4
      protobuf_deps.bzl
  27. 2
      python/google/protobuf/internal/any_test.proto
  28. 64
      python/google/protobuf/internal/descriptor_pool_test.py
  29. 1
      python/google/protobuf/internal/descriptor_pool_test1.proto
  30. 4
      python/google/protobuf/internal/descriptor_pool_test2.proto
  31. 10
      python/google/protobuf/internal/descriptor_test.py
  32. 3
      python/google/protobuf/internal/factory_test2.proto
  33. 4
      python/google/protobuf/internal/file_options_test.proto
  34. 3
      python/google/protobuf/internal/message_set_extensions.proto
  35. 4
      python/google/protobuf/internal/missing_enum_values.proto
  36. 4
      python/google/protobuf/internal/more_extensions_dynamic.proto
  37. 2
      python/google/protobuf/internal/no_package.proto
  38. 51
      python/google/protobuf/internal/packed_field_test.proto
  39. 2
      python/google/protobuf/pyext/message.cc
  40. 13
      src/file_lists.cmake
  41. 2
      src/google/protobuf/BUILD.bazel
  42. 2
      src/google/protobuf/any.proto
  43. 2
      src/google/protobuf/api.proto
  44. 5
      src/google/protobuf/arena_align.h
  45. 4
      src/google/protobuf/arena_cleanup.h
  46. 2
      src/google/protobuf/arena_config.cc
  47. 7
      src/google/protobuf/compiler/command_line_interface.cc
  48. 8
      src/google/protobuf/compiler/command_line_interface.h
  49. 2
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  50. 13
      src/google/protobuf/compiler/cpp/enum.cc
  51. 2
      src/google/protobuf/compiler/cpp/enum_field.cc
  52. 35
      src/google/protobuf/compiler/cpp/file.cc
  53. 20
      src/google/protobuf/compiler/cpp/generator.cc
  54. 45
      src/google/protobuf/compiler/cpp/helpers.cc
  55. 1
      src/google/protobuf/compiler/cpp/helpers.h
  56. 4
      src/google/protobuf/compiler/cpp/map_field.cc
  57. 42
      src/google/protobuf/compiler/cpp/message.cc
  58. 3
      src/google/protobuf/compiler/cpp/message_field.cc
  59. 66
      src/google/protobuf/compiler/cpp/parse_function_generator.cc
  60. 4
      src/google/protobuf/compiler/cpp/primitive_field.cc
  61. 11
      src/google/protobuf/compiler/cpp/string_field.cc
  62. 5
      src/google/protobuf/compiler/cpp/test_bad_identifiers.proto
  63. 1
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  64. 2
      src/google/protobuf/compiler/csharp/csharp_map_field.cc
  65. 3
      src/google/protobuf/compiler/importer_unittest.cc
  66. 4
      src/google/protobuf/compiler/java/generator.cc
  67. 6
      src/google/protobuf/compiler/java/helpers.cc
  68. 1
      src/google/protobuf/compiler/objectivec/BUILD.bazel
  69. 6
      src/google/protobuf/compiler/objectivec/enum.cc
  70. 2
      src/google/protobuf/compiler/objectivec/enum.h
  71. 7
      src/google/protobuf/compiler/objectivec/enum_field.cc
  72. 18
      src/google/protobuf/compiler/objectivec/enum_field.h
  73. 7
      src/google/protobuf/compiler/objectivec/extension.cc
  74. 4
      src/google/protobuf/compiler/objectivec/extension.h
  75. 39
      src/google/protobuf/compiler/objectivec/field.cc
  76. 58
      src/google/protobuf/compiler/objectivec/field.h
  77. 31
      src/google/protobuf/compiler/objectivec/file.cc
  78. 22
      src/google/protobuf/compiler/objectivec/file.h
  79. 18
      src/google/protobuf/compiler/objectivec/generator.cc
  80. 5
      src/google/protobuf/compiler/objectivec/generator.h
  81. 25
      src/google/protobuf/compiler/objectivec/helpers.cc
  82. 2
      src/google/protobuf/compiler/objectivec/helpers.h
  83. 18
      src/google/protobuf/compiler/objectivec/import_writer.cc
  84. 3
      src/google/protobuf/compiler/objectivec/import_writer.h
  85. 30
      src/google/protobuf/compiler/objectivec/line_consumer.cc
  86. 7
      src/google/protobuf/compiler/objectivec/line_consumer.h
  87. 9
      src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc
  88. 19
      src/google/protobuf/compiler/objectivec/map_field.cc
  89. 13
      src/google/protobuf/compiler/objectivec/map_field.h
  90. 11
      src/google/protobuf/compiler/objectivec/message.cc
  91. 3
      src/google/protobuf/compiler/objectivec/message.h
  92. 6
      src/google/protobuf/compiler/objectivec/message_field.cc
  93. 20
      src/google/protobuf/compiler/objectivec/message_field.h
  94. 192
      src/google/protobuf/compiler/objectivec/names.cc
  95. 77
      src/google/protobuf/compiler/objectivec/names.h
  96. 2
      src/google/protobuf/compiler/objectivec/names_unittest.cc
  97. 6
      src/google/protobuf/compiler/objectivec/oneof.cc
  98. 7
      src/google/protobuf/compiler/objectivec/oneof.h
  99. 22
      src/google/protobuf/compiler/objectivec/primitive_field.cc
  100. 13
      src/google/protobuf/compiler/objectivec/primitive_field.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,35 +1 @@
build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14 build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
build:dbg --compilation_mode=dbg
build:opt --compilation_mode=opt
build:san-common --config=dbg --strip=never --copt=-O0 --copt=-fno-omit-frame-pointer
build:asan --config=san-common --copt=-fsanitize=address --linkopt=-fsanitize=address
build:asan --copt=-DADDRESS_SANITIZER=1
# ASAN hits ODR violations with shared linkage due to rules_proto.
build:asan --dynamic_mode=off
build:msan --config=san-common --copt=-fsanitize=memory --linkopt=-fsanitize=memory
build:msan --copt=-fsanitize-memory-track-origins
build:msan --copt=-fsanitize-memory-use-after-dtor
build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1
build:msan --copt=-DMEMORY_SANITIZER=1
# Use our instrumented LLVM libc++ in Kokoro.
build:kokoro-msan --config=msan
build:kokoro-msan --linkopt=-L/opt/libcxx_msan/lib
build:kokoro-msan --linkopt=-Wl,-rpath,/opt/libcxx_msan/lib
build:kokoro-msan --cxxopt=-stdlib=libc++ --linkopt=-stdlib=libc++
build:tsan --config=san-common --copt=-fsanitize=thread --linkopt=-fsanitize=thread
build:tsan --copt=-DTHREAD_SANITIZER=1
build:ubsan --config=san-common --copt=-fsanitize=undefined --linkopt=-fsanitize=undefined
build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1
build:ubsan --copt=-DUNDEFINED_SANITIZER=1
# Workaround for the fact that Bazel links with $CC, not $CXX
# https://github.com/bazelbuild/bazel/issues/11122#issuecomment-613746748
build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr

@ -330,6 +330,7 @@ set_property(CACHE protobuf_ABSL_PROVIDER PROPERTY STRINGS "module" "package")
include(${protobuf_SOURCE_DIR}/cmake/abseil-cpp.cmake) include(${protobuf_SOURCE_DIR}/cmake/abseil-cpp.cmake)
if (protobuf_BUILD_PROTOBUF_BINARIES) if (protobuf_BUILD_PROTOBUF_BINARIES)
include(${protobuf_SOURCE_DIR}/cmake/utf8_range.cmake)
include(${protobuf_SOURCE_DIR}/cmake/libprotobuf-lite.cmake) include(${protobuf_SOURCE_DIR}/cmake/libprotobuf-lite.cmake)
if (NOT DEFINED protobuf_LIB_PROTOBUF_LITE) if (NOT DEFINED protobuf_LIB_PROTOBUF_LITE)
set(protobuf_LIB_PROTOBUF_LITE libprotobuf-lite) set(protobuf_LIB_PROTOBUF_LITE libprotobuf-lite)

@ -2,18 +2,18 @@
COPTS = select({ COPTS = select({
"//build_defs:config_msvc": [ "//build_defs:config_msvc": [
"/wd4065", # switch statement contains 'default' but no 'case' labels "/wd4065", # switch statement contains 'default' but no 'case' labels
"/wd4244", # 'conversion' conversion from 'type1' to 'type2', possible loss of data "/wd4244", # 'conversion' conversion from 'type1' to 'type2', possible loss of data
"/wd4251", # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' "/wd4251", # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
"/wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data "/wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data
"/wd4305", # 'identifier' : truncation from 'type1' to 'type2' "/wd4305", # 'identifier' : truncation from 'type1' to 'type2'
"/wd4307", # 'operator' : integral constant overflow "/wd4307", # 'operator' : integral constant overflow
"/wd4309", # 'conversion' : truncation of constant value "/wd4309", # 'conversion' : truncation of constant value
"/wd4334", # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) "/wd4334", # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
"/wd4355", # 'this' : used in base member initializer list "/wd4355", # 'this' : used in base member initializer list
"/wd4506", # no definition for inline function 'function' "/wd4506", # no definition for inline function 'function'
"/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning) "/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning)
"/wd4996", # The compiler encountered a deprecated declaration. "/wd4996", # The compiler encountered a deprecated declaration.
], ],
"//conditions:default": [ "//conditions:default": [
"-DHAVE_ZLIB", "-DHAVE_ZLIB",
@ -22,6 +22,7 @@ COPTS = select({
"-Werror", "-Werror",
], ],
}) })
# Android and MSVC builds do not need to link in a separate pthread library. # Android and MSVC builds do not need to link in a separate pthread library.
LINK_OPTS = select({ LINK_OPTS = select({
"//build_defs:config_android": [], "//build_defs:config_android": [],

@ -34,3 +34,6 @@ set_target_properties(libprotobuf-lite PROPERTIES
OUTPUT_NAME ${LIB_PREFIX}protobuf-lite OUTPUT_NAME ${LIB_PREFIX}protobuf-lite
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
add_library(protobuf::libprotobuf-lite ALIAS libprotobuf-lite) add_library(protobuf::libprotobuf-lite ALIAS libprotobuf-lite)
target_include_directories(libprotobuf-lite PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/utf8_range)
target_link_libraries(libprotobuf-lite PRIVATE utf8_validity)

@ -37,3 +37,6 @@ set_target_properties(libprotobuf PROPERTIES
OUTPUT_NAME ${LIB_PREFIX}protobuf OUTPUT_NAME ${LIB_PREFIX}protobuf
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
add_library(protobuf::libprotobuf ALIAS libprotobuf) add_library(protobuf::libprotobuf ALIAS libprotobuf)
target_include_directories(libprotobuf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/utf8_range)
target_link_libraries(libprotobuf PRIVATE utf8_validity)

@ -0,0 +1,12 @@
set(utf8_range_ENABLE_TESTS OFF)
if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/utf8_range/CMakeLists.txt")
message(FATAL_ERROR
"Cannot find third_party/utf8_range directory that's needed to "
"build conformance tests. If you use git, make sure you have cloned "
"submodules:\n"
" git submodule update --init --recursive\n")
endif()
set(utf8_range_ENABLE_INSTALL ${protobuf_INSTALL})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/utf8_range third_party/utf8_range)

@ -5,7 +5,6 @@ load("//:protobuf.bzl", "internal_csharp_proto_library", "internal_objc_proto_li
load("//build_defs:internal_shell.bzl", "inline_sh_binary") load("//build_defs:internal_shell.bzl", "inline_sh_binary")
load( load(
"@rules_pkg//:mappings.bzl", "@rules_pkg//:mappings.bzl",
"pkg_attributes",
"pkg_filegroup", "pkg_filegroup",
"pkg_files", "pkg_files",
"strip_prefix", "strip_prefix",
@ -149,10 +148,10 @@ cc_library(
hdrs = ["binary_json_conformance_suite.h"], hdrs = ["binary_json_conformance_suite.h"],
deps = [ deps = [
":conformance_test", ":conformance_test",
"@jsoncpp//:jsoncpp",
":test_messages_proto2_proto_cc", ":test_messages_proto2_proto_cc",
":test_messages_proto3_proto_cc", ":test_messages_proto3_proto_cc",
"@com_google_absl//absl/status", "@com_google_absl//absl/status",
"@jsoncpp",
], ],
) )

@ -202,6 +202,9 @@ public class SingleFieldBuilder<
builder = null; builder = null;
} }
onChanged(); onChanged();
// After clearing, parent is dirty, but this field builder is now clean and any changes should
// trickle up.
isClean = true;
return this; return this;
} }

@ -202,6 +202,9 @@ public class SingleFieldBuilderV3<
builder = null; builder = null;
} }
onChanged(); onChanged();
// After clearing, parent is dirty, but this field builder is now clean and any changes should
// trickle up.
isClean = true;
return this; return this;
} }

@ -33,6 +33,7 @@ package com.google.protobuf;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import protobuf_unittest.Engine; import protobuf_unittest.Engine;
import protobuf_unittest.TimingBelt;
import protobuf_unittest.Vehicle; import protobuf_unittest.Vehicle;
import protobuf_unittest.Wheel; import protobuf_unittest.Wheel;
import java.util.ArrayList; import java.util.ArrayList;
@ -48,6 +49,27 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public class NestedBuildersTest { public class NestedBuildersTest {
@Test
public void test3LayerPropagationWithIntermediateClear() {
Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
vehicleBuilder.getEngineBuilder().getTimingBeltBuilder();
// This step detaches the TimingBelt.Builder (though it leaves a SingleFieldBuilder in place)
vehicleBuilder.getEngineBuilder().clear();
// These steps build the middle and top level messages, it used to leave the vestigial
// TimingBelt.Builder in a state where further changes didn't propagate anymore
Object unused = vehicleBuilder.getEngineBuilder().build();
unused = vehicleBuilder.build();
TimingBelt expected = TimingBelt.newBuilder().setNumberOfTeeth(124).build();
vehicleBuilder.getEngineBuilder().setTimingBelt(expected);
// Testing that b/254158939 is fixed. It used to be that the setTimingBelt call above didn't
// propagate a change notification and the call below would return a stale version of the timing
// belt.
assertThat(vehicleBuilder.getEngine().getTimingBelt()).isEqualTo(expected);
}
@Test @Test
public void testMessagesAndBuilders() { public void testMessagesAndBuilders() {
Vehicle.Builder vehicleBuilder = Vehicle.newBuilder(); Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();

@ -30,8 +30,8 @@
syntax = "proto2"; syntax = "proto2";
package map_for_proto2_lite_test; package map_for_proto2_lite_test;
option java_outer_classname = "MapForProto2TestProto"; option java_outer_classname = "MapForProto2TestProto";
option optimize_for = LITE_RUNTIME; option optimize_for = LITE_RUNTIME;
option java_package = "map_lite_test"; option java_package = "map_lite_test";

@ -45,6 +45,11 @@ message Vehicle {
message Engine { message Engine {
optional int32 cylinder = 1; optional int32 cylinder = 1;
optional int32 liters = 2; optional int32 liters = 2;
optional TimingBelt timing_belt = 3;
}
message TimingBelt {
optional int32 number_of_teeth = 1;
} }
message Wheel { message Wheel {

@ -37,22 +37,19 @@ import com.google.protobuf.GeneratedMessageLite
operator fun < operator fun <
M : GeneratedMessageLite.ExtendableMessage<M, *>, M : GeneratedMessageLite.ExtendableMessage<M, *>,
MOrBT : GeneratedMessageLite.ExtendableMessageOrBuilder<M, *>, MOrBT : GeneratedMessageLite.ExtendableMessageOrBuilder<M, *>,
T : Any T : Any> MOrBT.get(extension: ExtensionLite<M, T>): T = getExtension(extension)
> MOrBT.get(extension: ExtensionLite<M, T>): T = getExtension(extension)
/** Sets the current value of the proto extension in this builder. */ /** Sets the current value of the proto extension in this builder. */
operator fun < operator fun <
M : GeneratedMessageLite.ExtendableMessage<M, B>, M : GeneratedMessageLite.ExtendableMessage<M, B>,
B : GeneratedMessageLite.ExtendableBuilder<M, B>, B : GeneratedMessageLite.ExtendableBuilder<M, B>,
T : Any T : Any> B.set(extension: ExtensionLite<M, T>, value: T) {
> B.set(extension: ExtensionLite<M, T>, value: T) {
setExtension(extension, value) setExtension(extension, value)
} }
/** Returns true if the specified extension is set. */ /** Returns true if the specified extension is set. */
operator fun < operator fun <
M : GeneratedMessageLite.ExtendableMessage<M, *>, M : GeneratedMessageLite.ExtendableMessage<M, *>,
MorBT : GeneratedMessageLite.ExtendableMessageOrBuilder<M, *> MorBT : GeneratedMessageLite.ExtendableMessageOrBuilder<M, *>> MorBT.contains(
> MorBT.contains(
extension: ExtensionLite<M, *> extension: ExtensionLite<M, *>
): Boolean = hasExtension(extension) ): Boolean = hasExtension(extension)

@ -48,31 +48,27 @@ class ExtendableMessageLiteExtensionsTest {
@Test @Test
fun getOnBuilder() { fun getOnBuilder() {
val builder = ExampleExtensibleMessage.newBuilder() val builder = ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6)
.setExtension(TestProto.int32Extension, 6)
assertThat(builder[TestProto.int32Extension]).isEqualTo(6) assertThat(builder[TestProto.int32Extension]).isEqualTo(6)
} }
@Test @Test
fun getOnMessage() { fun getOnMessage() {
val message = ExampleExtensibleMessage.newBuilder() val message =
.setExtension(TestProto.int32Extension, 6) ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6).build()
.build()
assertThat(message[TestProto.int32Extension]).isEqualTo(6) assertThat(message[TestProto.int32Extension]).isEqualTo(6)
} }
@Test @Test
fun containsPositiveOnMessage() { fun containsPositiveOnMessage() {
val message = ExampleExtensibleMessage.newBuilder() val message =
.setExtension(TestProto.int32Extension, 6) ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6).build()
.build()
assertThat(TestProto.int32Extension in message).isTrue() assertThat(TestProto.int32Extension in message).isTrue()
} }
@Test @Test
fun containsPositiveOnBuilder() { fun containsPositiveOnBuilder() {
val builder = ExampleExtensibleMessage.newBuilder() val builder = ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6)
.setExtension(TestProto.int32Extension, 6)
assertThat(TestProto.int32Extension in builder).isTrue() assertThat(TestProto.int32Extension in builder).isTrue()
} }

@ -35,13 +35,13 @@ package com.google.protobuf.kotlin
* extension methods. * extension methods.
* *
* <p>This class is used by Kotlin protocol buffer extensions, and its constructor is public only * <p>This class is used by Kotlin protocol buffer extensions, and its constructor is public only
* because generated message code is in a different compilation unit. Others should not use this * because generated message code is in a different compilation unit. Others should not use this
* class directly in any way. * class directly in any way.
*/ */
@Suppress("unused") // the unused type parameter @Suppress("unused") // the unused type parameter
class DslList<E, P : DslProxy> @OnlyForUseByGeneratedProtoCode constructor( class DslList<E, P : DslProxy>
private val delegate: List<E> @OnlyForUseByGeneratedProtoCode
) : List<E> by delegate { constructor(private val delegate: List<E>) : List<E> by delegate {
override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator()) override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator())
override fun listIterator(): ListIterator<E> = UnmodifiableListIterator(delegate.listIterator()) override fun listIterator(): ListIterator<E> = UnmodifiableListIterator(delegate.listIterator())

@ -35,13 +35,13 @@ package com.google.protobuf.kotlin
* extension methods. * extension methods.
* *
* <p>This class is used by Kotlin protocol buffer extensions, and its constructor is public only * <p>This class is used by Kotlin protocol buffer extensions, and its constructor is public only
* because generated message code is in a different compilation unit. Others should not use this * because generated message code is in a different compilation unit. Others should not use this
* class directly in any way. * class directly in any way.
*/ */
@Suppress("unused") // the unused type parameter @Suppress("unused") // the unused type parameter
class DslMap<K, V, P : DslProxy> @OnlyForUseByGeneratedProtoCode constructor( class DslMap<K, V, P : DslProxy>
private val delegate: Map<K, V> @OnlyForUseByGeneratedProtoCode
) : Map<K, V> by delegate { constructor(private val delegate: Map<K, V>) : Map<K, V> by delegate {
// We allocate the wrappers on calls to get, not with lazy {...}, because lazy allocates // We allocate the wrappers on calls to get, not with lazy {...}, because lazy allocates
// a few objects up front, and any kind of query operation on this object should be rare. // a few objects up front, and any kind of query operation on this object should be rare.

@ -31,9 +31,9 @@
package com.google.protobuf.kotlin package com.google.protobuf.kotlin
/** /**
* A type meaningful only for its existence, never intended to be instantiated. For example, * A type meaningful only for its existence, never intended to be instantiated. For example, a
* a `DslList<Int, FooProxy>` can be given different extension methods than a * `DslList<Int, FooProxy>` can be given different extension methods than a `DslList<Int,
* `DslList<Int, BarProxy>`. * BarProxy>`.
*/ */
abstract class DslProxy @OnlyForUseByGeneratedProtoCode protected constructor() { abstract class DslProxy @OnlyForUseByGeneratedProtoCode protected constructor() {
init { init {

@ -33,12 +33,11 @@ package com.google.protobuf.kotlin
import com.google.protobuf.ExtensionLite import com.google.protobuf.ExtensionLite
import com.google.protobuf.GeneratedMessageV3 import com.google.protobuf.GeneratedMessageV3
/** Sets the current value of the proto extension in this builder.*/ /** Sets the current value of the proto extension in this builder. */
operator fun < operator fun <
M : GeneratedMessageV3.ExtendableMessage<M>, M : GeneratedMessageV3.ExtendableMessage<M>,
B : GeneratedMessageV3.ExtendableBuilder<M, B>, B : GeneratedMessageV3.ExtendableBuilder<M, B>,
T : Any T : Any> B.set(extension: ExtensionLite<M, T>, value: T) {
> B.set(extension: ExtensionLite<M, T>, value: T) {
setExtension(extension, value) setExtension(extension, value)
} }
@ -46,11 +45,11 @@ operator fun <
operator fun < operator fun <
M : GeneratedMessageV3.ExtendableMessage<M>, M : GeneratedMessageV3.ExtendableMessage<M>,
MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder<M>, MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder<M>,
T : Any T : Any> MorBT.get(extension: ExtensionLite<M, T>): T = getExtension(extension)
> MorBT.get(extension: ExtensionLite<M, T>): T = getExtension(extension)
/** Returns true if the specified extension is set on this builder. */ /** Returns true if the specified extension is set on this builder. */
operator fun < operator fun <
M : GeneratedMessageV3.ExtendableMessage<M>, M : GeneratedMessageV3.ExtendableMessage<M>,
MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder<M> MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder<M>> MorBT.contains(
> MorBT.contains(extension: ExtensionLite<M, *>): Boolean = hasExtension(extension) extension: ExtensionLite<M, *>
): Boolean = hasExtension(extension)

@ -32,8 +32,8 @@ package com.google.protobuf.kotlin
/** /**
* Opt-in annotation to make it difficult to accidentally use APIs only intended for use by proto * Opt-in annotation to make it difficult to accidentally use APIs only intended for use by proto
* generated code. See https://kotlinlang.org/docs/reference/opt-in-requirements.html for details * generated code. See https://kotlinlang.org/docs/reference/opt-in-requirements.html for details on
* on how this API works. * how this API works.
*/ */
@RequiresOptIn( @RequiresOptIn(
message = message =

@ -30,9 +30,7 @@
package com.google.protobuf.kotlin package com.google.protobuf.kotlin
/** /** Indicates an API that is part of a DSL to generate protocol buffer messages. */
* Indicates an API that is part of a DSL to generate protocol buffer messages.
*/
@DslMarker @DslMarker
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY) @Retention(AnnotationRetention.BINARY)

@ -34,29 +34,24 @@ package com.google.protobuf.kotlin
internal class UnmodifiableIterator<E>(delegate: Iterator<E>) : Iterator<E> by delegate internal class UnmodifiableIterator<E>(delegate: Iterator<E>) : Iterator<E> by delegate
/** Wraps a [ListIterator] and makes it unmodifiable even from Java. */ /** Wraps a [ListIterator] and makes it unmodifiable even from Java. */
internal class UnmodifiableListIterator<E>( internal class UnmodifiableListIterator<E>(delegate: ListIterator<E>) : ListIterator<E> by delegate
delegate: ListIterator<E>
) : ListIterator<E> by delegate
/** Wraps a [Collection] and makes it unmodifiable even from Java. */ /** Wraps a [Collection] and makes it unmodifiable even from Java. */
internal open class UnmodifiableCollection<E>( internal open class UnmodifiableCollection<E>(private val delegate: Collection<E>) :
private val delegate: Collection<E> Collection<E> by delegate {
) : Collection<E> by delegate {
override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator()) override fun iterator(): Iterator<E> = UnmodifiableIterator(delegate.iterator())
} }
/** Wraps a [Set] and makes it unmodifiable even from Java. */ /** Wraps a [Set] and makes it unmodifiable even from Java. */
internal class UnmodifiableSet<E>( internal class UnmodifiableSet<E>(delegate: Collection<E>) :
delegate: Collection<E> UnmodifiableCollection<E>(delegate), Set<E>
) : UnmodifiableCollection<E>(delegate), Set<E>
/** Wraps a [Map.Entry] and makes it unmodifiable even from Java. */ /** Wraps a [Map.Entry] and makes it unmodifiable even from Java. */
internal class UnmodifiableMapEntry<K, V>(delegate: Map.Entry<K, V>) : Map.Entry<K, V> by delegate internal class UnmodifiableMapEntry<K, V>(delegate: Map.Entry<K, V>) : Map.Entry<K, V> by delegate
/** Wraps a [Set] of map entries and makes it unmodifiable even from Java. */ /** Wraps a [Set] of map entries and makes it unmodifiable even from Java. */
internal class UnmodifiableMapEntries<K, V>( internal class UnmodifiableMapEntries<K, V>(private val delegate: Set<Map.Entry<K, V>>) :
private val delegate: Set<Map.Entry<K, V>> UnmodifiableCollection<Map.Entry<K, V>>(delegate), Set<Map.Entry<K, V>> {
) : UnmodifiableCollection<Map.Entry<K, V>>(delegate), Set<Map.Entry<K, V>> {
// Is this overkill? Probably. // Is this overkill? Probably.

@ -67,9 +67,7 @@ class DslListTest {
fun dslListIsNotEvenSecretlyMutable() { fun dslListIsNotEvenSecretlyMutable() {
val dslList = DslList<Int, DummyProxy>(mutableListOf(1, 2, 3)) val dslList = DslList<Int, DummyProxy>(mutableListOf(1, 2, 3))
val dslListAsJavaUtil = dslList as java.util.List<Int> val dslListAsJavaUtil = dslList as java.util.List<Int>
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { dslListAsJavaUtil.add(4) }
dslListAsJavaUtil.add(4)
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -79,9 +77,7 @@ class DslListTest {
val iterator = dslList.iterator() as java.util.Iterator<Int> val iterator = dslList.iterator() as java.util.Iterator<Int>
iterator.next() iterator.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { iterator.remove() }
iterator.remove()
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -91,9 +87,7 @@ class DslListTest {
val iterator = dslList.listIterator() as java.util.ListIterator<Int> val iterator = dslList.listIterator() as java.util.ListIterator<Int>
iterator.next() iterator.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { iterator.remove() }
iterator.remove()
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -103,9 +97,7 @@ class DslListTest {
val iterator = dslList.listIterator(1) as java.util.ListIterator<Int> val iterator = dslList.listIterator(1) as java.util.ListIterator<Int>
iterator.next() iterator.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { iterator.remove() }
iterator.remove()
}
} }
@Test @Test

@ -44,8 +44,7 @@ class DslMapTest {
@Test @Test
fun matchesMap() { fun matchesMap() {
assertThat(DslMap<Int, Int, DummyProxy>(mapOf(1 to -1, 2 to -2))) assertThat(DslMap<Int, Int, DummyProxy>(mapOf(1 to -1, 2 to -2))).containsExactly(1, -1, 2, -2)
.containsExactly(1, -1, 2, -2)
} }
@Test @Test
@ -91,9 +90,7 @@ class DslMapTest {
fun dslMapIsNotEvenSecretlyMutable() { fun dslMapIsNotEvenSecretlyMutable() {
val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1)) val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
val dslMapAsJavaUtilMap = dslMap as java.util.Map<Int, Int> val dslMapAsJavaUtilMap = dslMap as java.util.Map<Int, Int>
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { dslMapAsJavaUtilMap.put(2, -2) }
dslMapAsJavaUtilMap.put(2, -2)
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -101,9 +98,7 @@ class DslMapTest {
fun dslMapKeysAreNotEvenSecretlyMutable() { fun dslMapKeysAreNotEvenSecretlyMutable() {
val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1)) val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
val dslMapKeysAsJavaUtilSet = dslMap.keys as java.util.Set<Int> val dslMapKeysAsJavaUtilSet = dslMap.keys as java.util.Set<Int>
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { dslMapKeysAsJavaUtilSet.remove(1) }
dslMapKeysAsJavaUtilSet.remove(1)
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -113,9 +108,7 @@ class DslMapTest {
val dslMapKeysAsJavaUtilSet = dslMap.keys as java.util.Set<Int> val dslMapKeysAsJavaUtilSet = dslMap.keys as java.util.Set<Int>
val itr = dslMapKeysAsJavaUtilSet.iterator() val itr = dslMapKeysAsJavaUtilSet.iterator()
itr.next() itr.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { itr.remove() }
itr.remove()
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -123,9 +116,7 @@ class DslMapTest {
fun dslMapValuesAreNotEvenSecretlyMutable() { fun dslMapValuesAreNotEvenSecretlyMutable() {
val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1)) val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
val dslMapValuesAsJavaUtilCollection = dslMap.values as java.util.Collection<Int> val dslMapValuesAsJavaUtilCollection = dslMap.values as java.util.Collection<Int>
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { dslMapValuesAsJavaUtilCollection.remove(1) }
dslMapValuesAsJavaUtilCollection.remove(1)
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -135,9 +126,7 @@ class DslMapTest {
val dslMapValuesAsJavaUtilCollection = dslMap.values as java.util.Collection<Int> val dslMapValuesAsJavaUtilCollection = dslMap.values as java.util.Collection<Int>
val itr = dslMapValuesAsJavaUtilCollection.iterator() val itr = dslMapValuesAsJavaUtilCollection.iterator()
itr.next() itr.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { itr.remove() }
itr.remove()
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -146,9 +135,7 @@ class DslMapTest {
val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1)) val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
val dslMapEntriesAsJavaUtilSet = dslMap.entries as java.util.Set<Map.Entry<Int, Int>> val dslMapEntriesAsJavaUtilSet = dslMap.entries as java.util.Set<Map.Entry<Int, Int>>
val entry = dslMap.entries.single() val entry = dslMap.entries.single()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { dslMapEntriesAsJavaUtilSet.remove(entry) }
dslMapEntriesAsJavaUtilSet.remove(entry)
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -158,9 +145,7 @@ class DslMapTest {
val dslMapEntriesAsJavaUtilSet = dslMap.entries as java.util.Set<Map.Entry<Int, Int>> val dslMapEntriesAsJavaUtilSet = dslMap.entries as java.util.Set<Map.Entry<Int, Int>>
val itr = dslMapEntriesAsJavaUtilSet.iterator() val itr = dslMapEntriesAsJavaUtilSet.iterator()
itr.next() itr.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { itr.remove() }
itr.remove()
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@ -168,9 +153,7 @@ class DslMapTest {
fun dslMapEntryObjectsAreNotEvenSecretlyMutable() { fun dslMapEntryObjectsAreNotEvenSecretlyMutable() {
val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1)) val dslMap = DslMap<Int, Int, DummyProxy>(mutableMapOf(1 to -1))
val dslMapEntryAsJavaUtilMapEntry = dslMap.entries.single() as java.util.Map.Entry<Int, Int> val dslMapEntryAsJavaUtilMapEntry = dslMap.entries.single() as java.util.Map.Entry<Int, Int>
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { dslMapEntryAsJavaUtilMapEntry.value = 2 }
dslMapEntryAsJavaUtilMapEntry.value = 2
}
} }
@Test @Test

@ -48,31 +48,27 @@ class ExtendableMessageExtensionsTest {
@Test @Test
fun getOnBuilder() { fun getOnBuilder() {
val builder = ExampleExtensibleMessage.newBuilder() val builder = ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6)
.setExtension(TestProto.int32Extension, 6)
assertThat(builder[TestProto.int32Extension]).isEqualTo(6) assertThat(builder[TestProto.int32Extension]).isEqualTo(6)
} }
@Test @Test
fun getOnMessage() { fun getOnMessage() {
val message = ExampleExtensibleMessage.newBuilder() val message =
.setExtension(TestProto.int32Extension, 6) ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6).build()
.build()
assertThat(message[TestProto.int32Extension]).isEqualTo(6) assertThat(message[TestProto.int32Extension]).isEqualTo(6)
} }
@Test @Test
fun containsPositiveOnMessage() { fun containsPositiveOnMessage() {
val message = ExampleExtensibleMessage.newBuilder() val message =
.setExtension(TestProto.int32Extension, 6) ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6).build()
.build()
assertThat(TestProto.int32Extension in message).isTrue() assertThat(TestProto.int32Extension in message).isTrue()
} }
@Test @Test
fun containsPositiveOnBuilder() { fun containsPositiveOnBuilder() {
val builder = ExampleExtensibleMessage.newBuilder() val builder = ExampleExtensibleMessage.newBuilder().setExtension(TestProto.int32Extension, 6)
.setExtension(TestProto.int32Extension, 6)
assertThat(TestProto.int32Extension in builder).isTrue() assertThat(TestProto.int32Extension in builder).isTrue()
} }

@ -48,90 +48,92 @@ class ExtensionListTest {
@Test @Test
fun matchesList() { fun matchesList() {
assertThat( assertThat(
ExtensionList<Int, ExampleExtensibleMessage>( ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, listOf(1, 2, 3))
TestProto.repeatedExtension, listOf(1, 2, 3)
) )
).containsExactly(1, 2, 3).inOrder() .containsExactly(1, 2, 3)
.inOrder()
} }
@Test @Test
fun reflectsChangesInList() { fun reflectsChangesInList() {
val mutableList = mutableListOf(1, 2, 3) val mutableList = mutableListOf(1, 2, 3)
val extensionList = ExtensionList<Int, ExampleExtensibleMessage>( val extensionList =
TestProto.repeatedExtension, mutableList ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, mutableList)
)
mutableList.add(4) mutableList.add(4)
assertThat(extensionList).containsExactly(1, 2, 3, 4).inOrder() assertThat(extensionList).containsExactly(1, 2, 3, 4).inOrder()
} }
@Test @Test
fun extensionListIsNotMutable() { fun extensionListIsNotMutable() {
val extensionList = ExtensionList<Int, ExampleExtensibleMessage>( val extensionList =
TestProto.repeatedExtension, mutableListOf(1, 2, 3) ExtensionList<Int, ExampleExtensibleMessage>(
) TestProto.repeatedExtension,
mutableListOf(1, 2, 3)
)
assertThat(extensionList is MutableList<*>).isFalse() assertThat(extensionList is MutableList<*>).isFalse()
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@Test @Test
fun extensionListIsNotEvenSecretlyMutable() { fun extensionListIsNotEvenSecretlyMutable() {
val extensionList = ExtensionList<Int, ExampleExtensibleMessage>( val extensionList =
TestProto.repeatedExtension, mutableListOf(1, 2, 3) ExtensionList<Int, ExampleExtensibleMessage>(
) TestProto.repeatedExtension,
mutableListOf(1, 2, 3)
)
val extensionListAsJavaUtil = extensionList as java.util.List<Int> val extensionListAsJavaUtil = extensionList as java.util.List<Int>
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { extensionListAsJavaUtil.add(4) }
extensionListAsJavaUtil.add(4)
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@Test @Test
fun extensionList_IteratorIsNotEvenSecretlyMutable() { fun extensionList_IteratorIsNotEvenSecretlyMutable() {
val extensionList = ExtensionList<Int, ExampleExtensibleMessage>( val extensionList =
TestProto.repeatedExtension, mutableListOf(1, 2, 3) ExtensionList<Int, ExampleExtensibleMessage>(
) TestProto.repeatedExtension,
mutableListOf(1, 2, 3)
)
val iterator = extensionList.iterator() as java.util.Iterator<Int> val iterator = extensionList.iterator() as java.util.Iterator<Int>
iterator.next() iterator.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { iterator.remove() }
iterator.remove()
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@Test @Test
fun extensionList_ListIteratorIsNotEvenSecretlyMutable() { fun extensionList_ListIteratorIsNotEvenSecretlyMutable() {
val extensionList = ExtensionList<Int, ExampleExtensibleMessage>( val extensionList =
TestProto.repeatedExtension, mutableListOf(1, 2, 3) ExtensionList<Int, ExampleExtensibleMessage>(
) TestProto.repeatedExtension,
mutableListOf(1, 2, 3)
)
val iterator = extensionList.listIterator() as java.util.ListIterator<Int> val iterator = extensionList.listIterator() as java.util.ListIterator<Int>
iterator.next() iterator.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { iterator.remove() }
iterator.remove()
}
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
@Test @Test
fun extensionList_ListIteratorIndexIsNotEvenSecretlyMutable() { fun extensionList_ListIteratorIndexIsNotEvenSecretlyMutable() {
val extensionList = ExtensionList<Int, ExampleExtensibleMessage>( val extensionList =
TestProto.repeatedExtension, mutableListOf(1, 2, 3) ExtensionList<Int, ExampleExtensibleMessage>(
) TestProto.repeatedExtension,
mutableListOf(1, 2, 3)
)
val iterator = extensionList.listIterator(1) as java.util.ListIterator<Int> val iterator = extensionList.listIterator(1) as java.util.ListIterator<Int>
iterator.next() iterator.next()
assertFailsWith<UnsupportedOperationException> { assertFailsWith<UnsupportedOperationException> { iterator.remove() }
iterator.remove()
}
} }
@Test @Test
fun expectedToString() { fun expectedToString() {
assertThat( assertThat(
ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, listOf(1, 2)) ExtensionList<Int, ExampleExtensibleMessage>(TestProto.repeatedExtension, listOf(1, 2))
.toString() .toString()
).isEqualTo("[1, 2]") )
.isEqualTo("[1, 2]")
} }
@Test @Test

@ -67,8 +67,8 @@ def protobuf_deps():
_github_archive( _github_archive(
name = "utf8_range", name = "utf8_range",
repo = "https://github.com/protocolbuffers/utf8_range", repo = "https://github.com/protocolbuffers/utf8_range",
commit = "45fbf543fec00020a08650791a37575319a3ea1d", commit = "a67b76f9f40107f2c78a5aa860bb6ce37ed83d85",
sha256 = "dd93db062025f563068abaa224549e9d341434b5851e959c7853dfa263c96416", sha256 = "de5f99318f3b5073dd99f3d4ca31e00e90a86cc400fb375e2147ae1fd41711ed",
) )
if not native.existing_rule("rules_cc"): if not native.existing_rule("rules_cc"):

@ -39,7 +39,7 @@ import "google/protobuf/any.proto";
message TestAny { message TestAny {
optional google.protobuf.Any value = 1; optional google.protobuf.Any value = 1;
optional int32 int_value = 2; optional int32 int_value = 2;
map<string,int32> map_value = 3; map<string, int32> map_value = 3;
extensions 10 to max; extensions 10 to max;
} }

@ -1127,33 +1127,49 @@ TEST1_FILE = ProtoFile(
TEST2_FILE = ProtoFile( TEST2_FILE = ProtoFile(
'google/protobuf/internal/descriptor_pool_test2.proto', 'google/protobuf/internal/descriptor_pool_test2.proto',
'google.protobuf.python.internal', 'google.protobuf.python.internal', {
{ 'DescriptorPoolTest3':
'DescriptorPoolTest3': MessageType({ MessageType(
'NestedEnum': EnumType([('NU', 13), ('XI', 14)]), {
'NestedMessage': MessageType({ 'NestedEnum':
'NestedEnum': EnumType([('OMICRON', 15), ('PI', 16)]), EnumType([('NU', 13), ('XI', 14)]),
'DeepNestedMessage': MessageType({ 'NestedMessage':
'NestedEnum': EnumType([('RHO', 17), ('SIGMA', 18)]), MessageType(
{
'NestedEnum':
EnumType([('OMICRON', 15), ('PI', 16)]),
'DeepNestedMessage':
MessageType(
{
'NestedEnum':
EnumType([('RHO', 17),
('SIGMA', 18)]),
}, [
('nested_enum',
EnumField(1, 'NestedEnum', 'RHO')),
('nested_field',
StringField(2, 'sigma')),
]),
}, [
('nested_enum', EnumField(
1, 'NestedEnum', 'PI')),
('nested_field', StringField(2, 'nu')),
('deep_nested_message',
MessageField(3, 'DeepNestedMessage')),
])
}, [ }, [
('nested_enum', EnumField(1, 'NestedEnum', 'RHO')), ('nested_enum', EnumField(1, 'NestedEnum', 'XI')),
('nested_field', StringField(2, 'sigma')), ('nested_message', MessageField(2, 'NestedMessage')),
],
extensions=[
('descriptor_pool_test',
ExtensionField(1001, 'DescriptorPoolTest1')),
]), ]),
}, [
('nested_enum', EnumField(1, 'NestedEnum', 'PI')),
('nested_field', StringField(2, 'nu')),
('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
])
}, [
('nested_enum', EnumField(1, 'NestedEnum', 'XI')),
('nested_message', MessageField(2, 'NestedMessage')),
], extensions=[
('descriptor_pool_test',
ExtensionField(1001, 'DescriptorPoolTest1')),
]),
}, },
dependencies=['google/protobuf/internal/descriptor_pool_test1.proto', dependencies=[
'google/protobuf/internal/more_messages.proto'], 'google/protobuf/internal/more_messages.proto',
'google/protobuf/internal/descriptor_pool_test1.proto',
],
public_dependencies=['google/protobuf/internal/more_messages.proto']) public_dependencies=['google/protobuf/internal/more_messages.proto'])

@ -32,7 +32,6 @@ syntax = "proto2";
package google.protobuf.python.internal; package google.protobuf.python.internal;
message DescriptorPoolTest1 { message DescriptorPoolTest1 {
extensions 1000 to max; extensions 1000 to max;

@ -32,12 +32,11 @@ syntax = "proto2";
package google.protobuf.python.internal; package google.protobuf.python.internal;
import "google/protobuf/internal/descriptor_pool_test1.proto";
import public "google/protobuf/internal/more_messages.proto"; import public "google/protobuf/internal/more_messages.proto";
import "google/protobuf/internal/descriptor_pool_test1.proto";
message DescriptorPoolTest3 { message DescriptorPoolTest3 {
extend DescriptorPoolTest1 { extend DescriptorPoolTest1 {
optional DescriptorPoolTest3 descriptor_pool_test = 1001; optional DescriptorPoolTest3 descriptor_pool_test = 1001;
} }
@ -70,4 +69,3 @@ message DescriptorPoolTest3 {
optional NestedMessage nested_message = 2; optional NestedMessage nested_message = 2;
} }

@ -823,6 +823,16 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
deprecated: true deprecated: true
> >
> >
field {
name: "deprecated_message"
number: 3
label: LABEL_OPTIONAL
type: TYPE_MESSAGE
type_name: ".protobuf_unittest.TestAllTypes.NestedMessage"
options {
deprecated: true
}
}
field { field {
name: "deprecated_int32_in_oneof" name: "deprecated_int32_in_oneof"
number: 2 number: 2

@ -36,7 +36,6 @@ package google.protobuf.python.internal;
import "google/protobuf/internal/factory_test1.proto"; import "google/protobuf/internal/factory_test1.proto";
enum Factory2Enum { enum Factory2Enum {
FACTORY_2_VALUE_0 = 0; FACTORY_2_VALUE_0 = 0;
FACTORY_2_VALUE_1 = 1; FACTORY_2_VALUE_1 = 1;
@ -73,7 +72,6 @@ message Factory2Message {
optional Factory2Enum enum_with_default = 20 [default = FACTORY_2_VALUE_1]; optional Factory2Enum enum_with_default = 20 [default = FACTORY_2_VALUE_1];
optional bytes bytes_with_default = 21 [default = "a\373\000c"]; optional bytes bytes_with_default = 21 [default = "a\373\000c"];
extend Factory1Message { extend Factory1Message {
optional string one_more_field = 1001; optional string one_more_field = 1001;
} }
@ -100,5 +98,6 @@ extend Factory1Message {
message MessageWithOption { message MessageWithOption {
option no_standard_descriptor_accessor = true; option no_standard_descriptor_accessor = true;
optional int32 field1 = 1; optional int32 field1 = 1;
} }

@ -30,10 +30,10 @@
syntax = "proto2"; syntax = "proto2";
import "google/protobuf/descriptor.proto";
package google.protobuf.python.internal; package google.protobuf.python.internal;
import "google/protobuf/descriptor.proto";
message FooOptions { message FooOptions {
optional string foo_name = 1; optional string foo_name = 1;
} }

@ -31,12 +31,13 @@
// This file contains messages that extend MessageSet. // This file contains messages that extend MessageSet.
syntax = "proto2"; syntax = "proto2";
package google.protobuf.internal;
package google.protobuf.internal;
// A message with message_set_wire_format. // A message with message_set_wire_format.
message TestMessageSet { message TestMessageSet {
option message_set_wire_format = true; option message_set_wire_format = true;
extensions 4 to max; extensions 4 to max;
} }

@ -43,7 +43,9 @@ message TestEnumValues {
} }
message TestMissingEnumValues { message TestMissingEnumValues {
enum NestedEnum { TWO = 2; } enum NestedEnum {
TWO = 2;
}
optional NestedEnum optional_nested_enum = 1; optional NestedEnum optional_nested_enum = 1;
repeated NestedEnum repeated_nested_enum = 2; repeated NestedEnum repeated_nested_enum = 2;
repeated NestedEnum packed_nested_enum = 3 [packed = true]; repeated NestedEnum packed_nested_enum = 3 [packed = true];

@ -36,10 +36,10 @@
syntax = "proto2"; syntax = "proto2";
import "google/protobuf/internal/more_extensions.proto";
package google.protobuf.internal; package google.protobuf.internal;
import "google/protobuf/internal/more_extensions.proto";
message DynamicMessageType { message DynamicMessageType {
optional int32 a = 1; optional int32 a = 1;
} }

@ -1,3 +1,5 @@
// NOLINT(no_package_specified): Test proto with no package
// Protocol Buffers - Google's data interchange format // Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved. // Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/ // https://developers.google.com/protocol-buffers/

@ -39,35 +39,36 @@ message TestPackedTypes {
BAZ = 2; BAZ = 2;
} }
repeated int32 repeated_int32 = 1; repeated int32 repeated_int32 = 1;
repeated int64 repeated_int64 = 2; repeated int64 repeated_int64 = 2;
repeated uint32 repeated_uint32 = 3; repeated uint32 repeated_uint32 = 3;
repeated uint64 repeated_uint64 = 4; repeated uint64 repeated_uint64 = 4;
repeated sint32 repeated_sint32 = 5; repeated sint32 repeated_sint32 = 5;
repeated sint64 repeated_sint64 = 6; repeated sint64 repeated_sint64 = 6;
repeated fixed32 repeated_fixed32 = 7; repeated fixed32 repeated_fixed32 = 7;
repeated fixed64 repeated_fixed64 = 8; repeated fixed64 repeated_fixed64 = 8;
repeated sfixed32 repeated_sfixed32 = 9; repeated sfixed32 repeated_sfixed32 = 9;
repeated sfixed64 repeated_sfixed64 = 10; repeated sfixed64 repeated_sfixed64 = 10;
repeated float repeated_float = 11; repeated float repeated_float = 11;
repeated double repeated_double = 12; repeated double repeated_double = 12;
repeated bool repeated_bool = 13; repeated bool repeated_bool = 13;
repeated NestedEnum repeated_nested_enum = 14; repeated NestedEnum repeated_nested_enum = 14;
} }
message TestUnpackedTypes { message TestUnpackedTypes {
repeated int32 repeated_int32 = 1 [packed = false]; repeated int32 repeated_int32 = 1 [packed = false];
repeated int64 repeated_int64 = 2 [packed = false]; repeated int64 repeated_int64 = 2 [packed = false];
repeated uint32 repeated_uint32 = 3 [packed = false]; repeated uint32 repeated_uint32 = 3 [packed = false];
repeated uint64 repeated_uint64 = 4 [packed = false]; repeated uint64 repeated_uint64 = 4 [packed = false];
repeated sint32 repeated_sint32 = 5 [packed = false]; repeated sint32 repeated_sint32 = 5 [packed = false];
repeated sint64 repeated_sint64 = 6 [packed = false]; repeated sint64 repeated_sint64 = 6 [packed = false];
repeated fixed32 repeated_fixed32 = 7 [packed = false]; repeated fixed32 repeated_fixed32 = 7 [packed = false];
repeated fixed64 repeated_fixed64 = 8 [packed = false]; repeated fixed64 repeated_fixed64 = 8 [packed = false];
repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; repeated sfixed32 repeated_sfixed32 = 9 [packed = false];
repeated sfixed64 repeated_sfixed64 = 10 [packed = false]; repeated sfixed64 repeated_sfixed64 = 10 [packed = false];
repeated float repeated_float = 11 [packed = false]; repeated float repeated_float = 11 [packed = false];
repeated double repeated_double = 12 [packed = false]; repeated double repeated_double = 12 [packed = false];
repeated bool repeated_bool = 13 [packed = false]; repeated bool repeated_bool = 13 [packed = false];
repeated TestPackedTypes.NestedEnum repeated_nested_enum = 14 [packed = false]; repeated TestPackedTypes.NestedEnum repeated_nested_enum = 14
[packed = false];
} }

@ -70,7 +70,7 @@
#include "google/protobuf/pyext/unknown_field_set.h" #include "google/protobuf/pyext/unknown_field_set.h"
#include "google/protobuf/pyext/unknown_fields.h" #include "google/protobuf/pyext/unknown_fields.h"
#include "google/protobuf/util/message_differencer.h" #include "google/protobuf/util/message_differencer.h"
#include "google/protobuf/stubs/strutil.h" #include "strings/util.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/strtod.h" #include "google/protobuf/io/strtod.h"

@ -72,10 +72,7 @@ set(libprotobuf_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/service.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/service.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/text_format.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/text_format.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/util/delimited_message_util.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/util/delimited_message_util.cc
@ -173,7 +170,6 @@ set(libprotobuf_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.h ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.h ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/service.h ${protobuf_SOURCE_DIR}/src/google/protobuf/service.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h
@ -181,7 +177,6 @@ set(libprotobuf_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/status_macros.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/status_macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.h
${protobuf_SOURCE_DIR}/src/google/protobuf/text_format.h ${protobuf_SOURCE_DIR}/src/google/protobuf/text_format.h
${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set.h ${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set.h
${protobuf_SOURCE_DIR}/src/google/protobuf/util/delimited_message_util.h ${protobuf_SOURCE_DIR}/src/google/protobuf/util/delimited_message_util.h
@ -220,10 +215,7 @@ set(libprotobuf_lite_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_lite.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_lite.cc
) )
@ -264,7 +256,6 @@ set(libprotobuf_lite_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/port.h ${protobuf_SOURCE_DIR}/src/google/protobuf/port.h
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.h ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.h ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h
@ -272,7 +263,6 @@ set(libprotobuf_lite_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/status_macros.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/status_macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.h
${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_lite.h ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_lite.h
) )
@ -725,8 +715,5 @@ set(util_test_protos_files
# //src/google/protobuf/stubs:test_srcs # //src/google/protobuf/stubs:test_srcs
set(stubs_test_files set(stubs_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil_unittest.cc
) )

@ -316,6 +316,7 @@ cc_library(
"@com_google_absl//absl/strings:internal", "@com_google_absl//absl/strings:internal",
"@com_google_absl//absl/synchronization", "@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time", "@com_google_absl//absl/time",
"@utf8_range//:utf8_validity",
], ],
) )
@ -385,6 +386,7 @@ cc_library(
"@com_google_absl//absl/strings:internal", "@com_google_absl//absl/strings:internal",
"@com_google_absl//absl/synchronization", "@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time", "@com_google_absl//absl/time",
"@utf8_range//:utf8_validity",
], ],
) )

@ -32,12 +32,12 @@ syntax = "proto3";
package google.protobuf; package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option go_package = "google.golang.org/protobuf/types/known/anypb"; option go_package = "google.golang.org/protobuf/types/known/anypb";
option java_package = "com.google.protobuf"; option java_package = "com.google.protobuf";
option java_outer_classname = "AnyProto"; option java_outer_classname = "AnyProto";
option java_multiple_files = true; option java_multiple_files = true;
option objc_class_prefix = "GPB"; option objc_class_prefix = "GPB";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
// `Any` contains an arbitrary serialized protocol buffer message along with a // `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message. // URL that describes the type of the serialized message.

@ -35,11 +35,11 @@ package google.protobuf;
import "google/protobuf/source_context.proto"; import "google/protobuf/source_context.proto";
import "google/protobuf/type.proto"; import "google/protobuf/type.proto";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option java_package = "com.google.protobuf"; option java_package = "com.google.protobuf";
option java_outer_classname = "ApiProto"; option java_outer_classname = "ApiProto";
option java_multiple_files = true; option java_multiple_files = true;
option objc_class_prefix = "GPB"; option objc_class_prefix = "GPB";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option go_package = "google.golang.org/protobuf/types/known/apipb"; option go_package = "google.golang.org/protobuf/types/known/apipb";
// Api is a light-weight descriptor for an API Interface. // Api is a light-weight descriptor for an API Interface.

@ -71,6 +71,9 @@
#include "google/protobuf/stubs/common.h" #include "google/protobuf/stubs/common.h"
#include "absl/numeric/bits.h" #include "absl/numeric/bits.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace internal { namespace internal {
@ -152,4 +155,6 @@ inline ArenaAlign ArenaAlignAs(size_t align) {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_ARENA_ALIGN_H__ #endif // GOOGLE_PROTOBUF_ARENA_ALIGN_H__

@ -40,6 +40,8 @@
#include "absl/base/attributes.h" #include "absl/base/attributes.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -186,4 +188,6 @@ inline ABSL_ATTRIBUTE_ALWAYS_INLINE size_t Size(void (*destructor)(void*)) {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_ARENA_CLEANUP_H__ #endif // GOOGLE_PROTOBUF_ARENA_CLEANUP_H__

@ -40,7 +40,7 @@ namespace google {
namespace protobuf { namespace protobuf {
namespace internal { namespace internal {
PROTOBUF_CONSTINIT const size_t kDefaultDefaultArenaMaxBlockSize = 8 << 10; PROTOBUF_CONSTINIT const size_t kDefaultDefaultArenaMaxBlockSize = 32 << 10;
namespace arena_config_internal { namespace arena_config_internal {

@ -60,7 +60,6 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -74,10 +73,12 @@
#include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/logging.h"
#include "google/protobuf/compiler/subprocess.h" #include "google/protobuf/compiler/subprocess.h"
#include "google/protobuf/compiler/plugin.pb.h" #include "google/protobuf/compiler/plugin.pb.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/match.h" #include "absl/strings/match.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/importer.h" #include "google/protobuf/compiler/importer.h"
@ -1073,7 +1074,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
if (!generator) { if (!generator) {
// First time we've seen this output location. // First time we've seen this output location.
generator.reset(new GeneratorContextImpl(parsed_files)); generator = std::make_unique<GeneratorContextImpl>(parsed_files);
} }
if (!GenerateOutput(parsed_files, output_directives_[i], if (!GenerateOutput(parsed_files, output_directives_[i],
@ -2252,7 +2253,7 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
io::Printer printer(&out, '$'); io::Printer printer(&out, '$');
for (int i = 0; i < output_filenames.size(); i++) { for (int i = 0; i < output_filenames.size(); i++) {
printer.Print(output_filenames[i].c_str()); printer.Print(output_filenames[i]);
if (i == output_filenames.size() - 1) { if (i == output_filenames.size() - 1) {
printer.Print(":"); printer.Print(":");
} else { } else {

@ -44,11 +44,11 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <string> #include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "google/protobuf/port.h" #include "google/protobuf/port.h"
@ -216,8 +216,8 @@ class PROTOC_EXPORT CommandLineInterface {
class ErrorPrinter; class ErrorPrinter;
class GeneratorContextImpl; class GeneratorContextImpl;
class MemoryOutputStream; class MemoryOutputStream;
typedef std::unordered_map<std::string, std::unique_ptr<GeneratorContextImpl>> using GeneratorContextMap =
GeneratorContextMap; absl::flat_hash_map<std::string, std::unique_ptr<GeneratorContextImpl>>;
// Clear state from previous Run(). // Clear state from previous Run().
void Clear(); void Clear();

@ -71,8 +71,6 @@
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h" #include "google/protobuf/io/zero_copy_stream.h"
#include "google/protobuf/stubs/strutil.h"
// Must be included last. // Must be included last.
#include "google/protobuf/port_def.inc" #include "google/protobuf/port_def.inc"

@ -165,9 +165,9 @@ void EnumGenerator::GenerateDefinition(io::Printer* p) {
p->LookupVar("Msg_Enum_"))}}, p->LookupVar("Msg_Enum_"))}},
R"cc( R"cc(
$Msg_Enum_Msg_Enum_$INT_MIN_SENTINEL_DO_NOT_USE_ = $Msg_Enum_Msg_Enum_$INT_MIN_SENTINEL_DO_NOT_USE_ =
std::numeric_limits<int32_t>::min(), std::numeric_limits<::int32_t>::min(),
$Msg_Enum_Msg_Enum_$INT_MAX_SENTINEL_DO_NOT_USE_ = $Msg_Enum_Msg_Enum_$INT_MAX_SENTINEL_DO_NOT_USE_ =
std::numeric_limits<int32_t>::max(), std::numeric_limits<::int32_t>::max(),
)cc"); )cc");
}}, }},
}, },
@ -289,9 +289,12 @@ void EnumGenerator::GenerateGetEnumDescriptorSpecializations(io::Printer* p) {
void EnumGenerator::GenerateSymbolImports(io::Printer* p) const { void EnumGenerator::GenerateSymbolImports(io::Printer* p) const {
auto v = p->WithVars(EnumVars(enum_, options_, limits_.min, limits_.max)); auto v = p->WithVars(EnumVars(enum_, options_, limits_.min, limits_.max));
p->Emit(R"cc( {
using $Enum_$ = $Msg_Enum$; auto a = p->WithVars({{"Enum_annotated", p->LookupVar("Enum_"), enum_}});
)cc"); p->Emit(R"cc(
using $Enum_annotated$ = $Msg_Enum$;
)cc");
}
for (int j = 0; j < enum_->value_count(); ++j) { for (int j = 0; j < enum_->value_count(); ++j) {
const auto* value = enum_->value(j); const auto* value = enum_->value(j);

@ -385,7 +385,7 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
format( format(
"{\n" "{\n"
" size_t data_size = 0;\n" " ::size_t data_size = 0;\n"
" unsigned int count = static_cast<unsigned " " unsigned int count = static_cast<unsigned "
"int>(this->_internal_$name$_size());"); "int>(this->_internal_$name$_size());");
format.Indent(); format.Indent();

@ -39,8 +39,6 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <string> #include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -53,7 +51,6 @@
#include "absl/strings/match.h" #include "absl/strings/match.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/strings/strip.h" #include "absl/strings/strip.h"
#include "google/protobuf/compiler/cpp/enum.h" #include "google/protobuf/compiler/cpp/enum.h"
@ -66,8 +63,6 @@
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
#include "google/protobuf/stubs/strutil.h" // for StringReplace.
// Must be last. // Must be last.
#include "google/protobuf/port_def.inc" #include "google/protobuf/port_def.inc"
@ -379,7 +374,7 @@ void FileGenerator::GeneratePBHeader(io::Printer* p,
void FileGenerator::DoIncludeFile(absl::string_view google3_name, void FileGenerator::DoIncludeFile(absl::string_view google3_name,
bool do_export, io::Printer* p) { bool do_export, io::Printer* p) {
absl::string_view prefix = "net/proto2/"; constexpr absl::string_view prefix = "net/proto2/";
GOOGLE_CHECK(absl::StartsWith(google3_name, prefix)) << google3_name; GOOGLE_CHECK(absl::StartsWith(google3_name, prefix)) << google3_name;
auto v = p->WithVars( auto v = p->WithVars(
@ -387,18 +382,24 @@ void FileGenerator::DoIncludeFile(absl::string_view google3_name,
if (options_.opensource_runtime) { if (options_.opensource_runtime) {
absl::ConsumePrefix(&google3_name, prefix); absl::ConsumePrefix(&google3_name, prefix);
std::string path(google3_name); absl::ConsumePrefix(&google3_name, "internal/");
absl::ConsumePrefix(&google3_name, "proto/");
absl::ConsumePrefix(&google3_name, "public/");
path = StringReplace(path, "internal/", "", false); std::string path;
path = StringReplace(path, "proto/", "", false); if (absl::ConsumePrefix(&google3_name, "io/public/")) {
path = StringReplace(path, "public/", "", false); path = absl::StrCat("io/", google3_name);
} else {
path = std::string(google3_name);
}
if (options_.runtime_include_base.empty()) { if (options_.runtime_include_base.empty()) {
p->Emit({{"path", path}}, R"( p->Emit({{"path", path}}, R"(
#include "google/protobuf/$path$"$ export_suffix$ #include "google/protobuf/$path$"$ export_suffix$
)"); )");
} else { } else {
p->Emit({{"base", options_.runtime_include_base}, {"path", path}}, R"( p->Emit({{"base", options_.runtime_include_base}, {"path", path}},
R"(
#include "$base$google/protobuf/$path$"$ export_suffix$ #include "$base$google/protobuf/$path$"$ export_suffix$
)"); )");
} }
@ -407,8 +408,10 @@ void FileGenerator::DoIncludeFile(absl::string_view google3_name,
// The bootstrapped proto generated code needs to use the // The bootstrapped proto generated code needs to use the
// third_party/protobuf header paths to avoid circular dependencies. // third_party/protobuf header paths to avoid circular dependencies.
if (options_.bootstrap) { if (options_.bootstrap) {
path = StringReplace(path, "net/proto2/public", "third_party/protobuf", constexpr absl::string_view bootstrap_prefix = "net/proto2/public";
false); if (absl::ConsumePrefix(&google3_name, bootstrap_prefix)) {
path = absl::StrCat("third_party/protobuf", google3_name);
}
} }
p->Emit({{"path", path}}, R"( p->Emit({{"path", path}}, R"(
@ -928,7 +931,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) {
}}, }},
}, },
R"cc( R"cc(
const uint32_t $tablename$::offsets[] PROTOBUF_SECTION_VARIABLE( const ::uint32_t $tablename$::offsets[] PROTOBUF_SECTION_VARIABLE(
protodesc_cold) = { protodesc_cold) = {
$offsets$, $offsets$,
}; };
@ -947,7 +950,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) {
// //
// MSVC doesn't like empty arrays, so we add a dummy. // MSVC doesn't like empty arrays, so we add a dummy.
p->Emit(R"cc( p->Emit(R"cc(
const uint32_t $tablename$::offsets[1] = {}; const ::uint32_t $tablename$::offsets[1] = {};
static constexpr ::_pbi::MigrationSchema* schemas = nullptr; static constexpr ::_pbi::MigrationSchema* schemas = nullptr;
static constexpr ::_pb::Message* const* file_default_instances = nullptr; static constexpr ::_pb::Message* const* file_default_instances = nullptr;
)cc"); )cc");
@ -1406,7 +1409,7 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(io::Printer* p) {
p->Emit(R"cc( p->Emit(R"cc(
// Internal implementation detail -- do not use these members. // Internal implementation detail -- do not use these members.
struct $dllexport_decl $$tablename$ { struct $dllexport_decl $$tablename$ {
static const uint32_t offsets[]; static const ::uint32_t offsets[];
}; };
)cc"); )cc");

@ -34,16 +34,14 @@
#include "google/protobuf/compiler/cpp/generator.h" #include "google/protobuf/compiler/cpp/generator.h"
#include <cstdlib>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "google/protobuf/stubs/strutil.h" #include "absl/strings/match.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "google/protobuf/compiler/cpp/file.h" #include "google/protobuf/compiler/cpp/file.h"
#include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
@ -63,12 +61,12 @@ absl::flat_hash_map<std::string, std::string> CommonVars(
return { return {
{"proto_ns", ProtobufNamespace(options)}, {"proto_ns", ProtobufNamespace(options)},
{"string", "std::string"}, {"string", "std::string"},
{"int8", "int8_t"}, {"int8", "::int8_t"},
{"int32", "int32_t"}, {"int32", "::int32_t"},
{"int64", "int64_t"}, {"int64", "::int64_t"},
{"uint8", "uint8_t"}, {"uint8", "::uint8_t"},
{"uint32", "uint32_t"}, {"uint32", "::uint32_t"},
{"uint64", "uint64_t"}, {"uint64", "::uint64_t"},
{"hrule_thick", kThickSeparator}, {"hrule_thick", kThickSeparator},
{"hrule_thin", kThinSeparator}, {"hrule_thin", kThinSeparator},
@ -152,7 +150,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime; file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime;
file_options.lite_implicit_weak_fields = true; file_options.lite_implicit_weak_fields = true;
if (!value.empty()) { if (!value.empty()) {
file_options.num_cc_files = strto32(value.c_str(), nullptr, 10); file_options.num_cc_files = std::strtol(value.c_str(), nullptr, 10);
} }
} else if (key == "proto_h") { } else if (key == "proto_h") {
file_options.proto_h = true; file_options.proto_h = true;

@ -49,13 +49,10 @@
#include "google/protobuf/stubs/common.h" #include "google/protobuf/stubs/common.h"
#include "google/protobuf/stubs/logging.h" #include "google/protobuf/stubs/logging.h"
#include "google/protobuf/compiler/scc.h" #include "google/protobuf/compiler/scc.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/dynamic_message.h" #include "google/protobuf/dynamic_message.h"
#include "google/protobuf/wire_format.h" #include "google/protobuf/wire_format.h"
#include "google/protobuf/wire_format_lite.h" #include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/stubs/strutil.h"
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h" #include "absl/container/flat_hash_set.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
@ -63,11 +60,13 @@
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include "absl/synchronization/mutex.h" #include "absl/synchronization/mutex.h"
#include "google/protobuf/compiler/cpp/names.h" #include "google/protobuf/compiler/cpp/names.h"
#include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/compiler/cpp/options.h"
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/strtod.h"
// Must be last. // Must be last.
@ -172,7 +171,6 @@ static const char* const kKeywordList[] = {
"while", "while",
"xor", "xor",
"xor_eq", "xor_eq",
#ifdef PROTOBUF_FUTURE_CPP20_KEYWORDS // C++20 keywords.
"char8_t", "char8_t",
"char16_t", "char16_t",
"char32_t", "char32_t",
@ -183,12 +181,11 @@ static const char* const kKeywordList[] = {
"co_return", "co_return",
"co_yield", "co_yield",
"requires", "requires",
#endif // !PROTOBUF_FUTURE_BREAKING_CHANGES
}; };
const absl::flat_hash_set<std::string>& Keywords() { const absl::flat_hash_set<absl::string_view>& Keywords() {
static const auto* keywords = [] { static const auto* keywords = [] {
auto* keywords = new absl::flat_hash_set<std::string>(); auto* keywords = new absl::flat_hash_set<absl::string_view>();
for (const auto keyword : kKeywordList) { for (const auto keyword : kKeywordList) {
keywords->emplace(keyword); keywords->emplace(keyword);
@ -199,7 +196,7 @@ const absl::flat_hash_set<std::string>& Keywords() {
} }
std::string IntTypeName(const Options& options, const std::string& type) { std::string IntTypeName(const Options& options, const std::string& type) {
return type + "_t"; return absl::StrCat("::", type, "_t");
} }
// Returns true if the message can potentially allocate memory for its field. // Returns true if the message can potentially allocate memory for its field.
@ -409,16 +406,18 @@ std::string Namespace(const std::string& package) {
} }
std::string Namespace(const FileDescriptor* d, const Options& options) { std::string Namespace(const FileDescriptor* d, const Options& options) {
std::string ret = Namespace(d->package()); std::string ns = Namespace(d->package());
if (IsWellKnownMessage(d) && options.opensource_runtime) { if (IsWellKnownMessage(d) && options.opensource_runtime) {
// Written with string concatenation to prevent rewriting of // Written with string concatenation to prevent rewriting of
// ::google::protobuf. // ::google::protobuf.
ret = StringReplace(ret, constexpr absl::string_view prefix =
"::google::" "::google::" // prevent clang-format reflowing
"protobuf", "protobuf";
"::PROTOBUF_NAMESPACE_ID", false); absl::string_view new_ns(ns);
absl::ConsumePrefix(&new_ns, prefix);
return absl::StrCat("::PROTOBUF_NAMESPACE_ID", new_ns);
} }
return ret; return ns;
} }
std::string Namespace(const Descriptor* d, const Options& options) { std::string Namespace(const Descriptor* d, const Options& options) {
@ -591,13 +590,13 @@ std::string StripProto(const std::string& filename) {
const char* PrimitiveTypeName(FieldDescriptor::CppType type) { const char* PrimitiveTypeName(FieldDescriptor::CppType type) {
switch (type) { switch (type) {
case FieldDescriptor::CPPTYPE_INT32: case FieldDescriptor::CPPTYPE_INT32:
return "int32_t"; return "::int32_t";
case FieldDescriptor::CPPTYPE_INT64: case FieldDescriptor::CPPTYPE_INT64:
return "int64_t"; return "::int64_t";
case FieldDescriptor::CPPTYPE_UINT32: case FieldDescriptor::CPPTYPE_UINT32:
return "uint32_t"; return "::uint32_t";
case FieldDescriptor::CPPTYPE_UINT64: case FieldDescriptor::CPPTYPE_UINT64:
return "uint64_t"; return "::uint64_t";
case FieldDescriptor::CPPTYPE_DOUBLE: case FieldDescriptor::CPPTYPE_DOUBLE:
return "double"; return "double";
case FieldDescriptor::CPPTYPE_FLOAT: case FieldDescriptor::CPPTYPE_FLOAT:
@ -713,13 +712,13 @@ static std::string Int64ToString(int64_t number) {
if (number == std::numeric_limits<int64_t>::min()) { if (number == std::numeric_limits<int64_t>::min()) {
// This needs to be special-cased, see explanation here: // This needs to be special-cased, see explanation here:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
return absl::StrCat("int64_t{", number + 1, "} - 1"); return absl::StrCat("::int64_t{", number + 1, "} - 1");
} }
return absl::StrCat("int64_t{", number, "}"); return absl::StrCat("::int64_t{", number, "}");
} }
static std::string UInt64ToString(uint64_t number) { static std::string UInt64ToString(uint64_t number) {
return absl::StrCat("uint64_t{", number, "u}"); return absl::StrCat("::uint64_t{", number, "u}");
} }
std::string DefaultValue(const FieldDescriptor* field) { std::string DefaultValue(const FieldDescriptor* field) {
@ -745,7 +744,7 @@ std::string DefaultValue(const Options& options, const FieldDescriptor* field) {
} else if (value != value) { } else if (value != value) {
return "std::numeric_limits<double>::quiet_NaN()"; return "std::numeric_limits<double>::quiet_NaN()";
} else { } else {
return SimpleDtoa(value); return io::SimpleDtoa(value);
} }
} }
case FieldDescriptor::CPPTYPE_FLOAT: { case FieldDescriptor::CPPTYPE_FLOAT: {
@ -757,7 +756,7 @@ std::string DefaultValue(const Options& options, const FieldDescriptor* field) {
} else if (value != value) { } else if (value != value) {
return "std::numeric_limits<float>::quiet_NaN()"; return "std::numeric_limits<float>::quiet_NaN()";
} else { } else {
std::string float_value = SimpleFtoa(value); std::string float_value = io::SimpleFtoa(value);
// If floating point value contains a period (.) or an exponent // If floating point value contains a period (.) or an exponent
// (either E or e), then append suffix 'f' to make it a float // (either E or e), then append suffix 'f' to make it a float
// literal. // literal.

@ -53,7 +53,6 @@
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/port.h" #include "google/protobuf/port.h"
#include "google/protobuf/stubs/strutil.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
// Must be included last. // Must be included last.

@ -30,12 +30,10 @@
#include "google/protobuf/compiler/cpp/map_field.h" #include "google/protobuf/compiler/cpp/map_field.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/wire_format.h" #include "google/protobuf/wire_format.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/helpers.h"
#include "absl/strings/str_cat.h"
#include "google/protobuf/stubs/strutil.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -42,7 +42,6 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <unordered_map>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -62,6 +61,7 @@
#include "google/protobuf/compiler/cpp/extension.h" #include "google/protobuf/compiler/cpp/extension.h"
#include "google/protobuf/compiler/cpp/field.h" #include "google/protobuf/compiler/cpp/field.h"
#include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/compiler/cpp/names.h"
#include "google/protobuf/compiler/cpp/padding_optimizer.h" #include "google/protobuf/compiler/cpp/padding_optimizer.h"
#include "google/protobuf/compiler/cpp/parse_function_generator.h" #include "google/protobuf/compiler/cpp/parse_function_generator.h"
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
@ -195,7 +195,7 @@ bool CanBeManipulatedAsRawBytes(const FieldDescriptor* field,
// RunMap maps from fields that start each run to the number of fields in that // RunMap maps from fields that start each run to the number of fields in that
// run. This is optimized for the common case that there are very few runs in // run. This is optimized for the common case that there are very few runs in
// a message and that most of the eligible fields appear together. // a message and that most of the eligible fields appear together.
using RunMap = std::unordered_map<const FieldDescriptor*, size_t>; using RunMap = absl::flat_hash_map<const FieldDescriptor*, size_t>;
RunMap FindRuns(const std::vector<const FieldDescriptor*>& fields, RunMap FindRuns(const std::vector<const FieldDescriptor*>& fields,
const std::function<bool(const FieldDescriptor*)>& predicate) { const std::function<bool(const FieldDescriptor*)>& predicate) {
RunMap runs; RunMap runs;
@ -237,18 +237,18 @@ bool EmitFieldNonDefaultCondition(io::Printer* p, const std::string& prefix,
format("if ($prefix$_internal_has_$name$()) {\n"); format("if ($prefix$_internal_has_$name$()) {\n");
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) { } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) {
format( format(
"static_assert(sizeof(uint32_t) == sizeof(float), \"Code assumes " "static_assert(sizeof(::uint32_t) == sizeof(float), \"Code assumes "
"uint32_t and float are the same size.\");\n" "::uint32_t and float are the same size.\");\n"
"float tmp_$name$ = $prefix$_internal_$name$();\n" "float tmp_$name$ = $prefix$_internal_$name$();\n"
"uint32_t raw_$name$;\n" "::uint32_t raw_$name$;\n"
"memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n" "memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n"
"if (raw_$name$ != 0) {\n"); "if (raw_$name$ != 0) {\n");
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE) { } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE) {
format( format(
"static_assert(sizeof(uint64_t) == sizeof(double), \"Code assumes " "static_assert(sizeof(::uint64_t) == sizeof(double), \"Code assumes "
"uint64_t and double are the same size.\");\n" "::uint64_t and double are the same size.\");\n"
"double tmp_$name$ = $prefix$_internal_$name$();\n" "double tmp_$name$ = $prefix$_internal_$name$();\n"
"uint64_t raw_$name$;\n" "::uint64_t raw_$name$;\n"
"memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n" "memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n"
"if (raw_$name$ != 0) {\n"); "if (raw_$name$ != 0) {\n");
} else { } else {
@ -1661,7 +1661,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) {
"PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;\n" "PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;\n"
"bool IsInitialized() const final;\n" "bool IsInitialized() const final;\n"
"\n" "\n"
"size_t ByteSizeLong() const final;\n"); "::size_t ByteSizeLong() const final;\n");
parse_function_generator_->GenerateMethodDecls(p); parse_function_generator_->GenerateMethodDecls(p);
@ -1833,7 +1833,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) {
num_required_fields_ > 1) { num_required_fields_ > 1) {
format( format(
"// helper for ByteSizeLong()\n" "// helper for ByteSizeLong()\n"
"size_t RequiredFieldsByteSizeFallback() const;\n\n"); "::size_t RequiredFieldsByteSizeFallback() const;\n\n");
} }
if (HasGeneratedMethods(descriptor_->file(), options_)) { if (HasGeneratedMethods(descriptor_->file(), options_)) {
@ -2103,12 +2103,12 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) {
format( format(
"using HasBits = " "using HasBits = "
"decltype(std::declval<$classname$>().$has_bits$);\n" "decltype(std::declval<$classname$>().$has_bits$);\n"
"static constexpr int32_t kHasBitsOffset =\n" "static constexpr ::int32_t kHasBitsOffset =\n"
" 8 * PROTOBUF_FIELD_OFFSET($classname$, _impl_._has_bits_);\n"); " 8 * PROTOBUF_FIELD_OFFSET($classname$, _impl_._has_bits_);\n");
} }
if (descriptor_->real_oneof_decl_count() > 0) { if (descriptor_->real_oneof_decl_count() > 0) {
format( format(
"static constexpr int32_t kOneofCaseOffset =\n" "static constexpr ::int32_t kOneofCaseOffset =\n"
" PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$);\n"); " PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$);\n");
} }
for (auto field : FieldRange(descriptor_)) { for (auto field : FieldRange(descriptor_)) {
@ -2731,7 +2731,7 @@ void MessageGenerator::GenerateCopyConstructorBody(io::Printer* p) const {
std::string pod_template = std::string pod_template =
"::memcpy(&$first$, &from.$first$,\n" "::memcpy(&$first$, &from.$first$,\n"
" static_cast<size_t>(reinterpret_cast<char*>(&$last$) -\n" " static_cast<::size_t>(reinterpret_cast<char*>(&$last$) -\n"
" reinterpret_cast<char*>(&$first$)) + sizeof($last$));\n"; " reinterpret_cast<char*>(&$first$)) + sizeof($last$));\n";
if (ShouldForceAllocationOnConstruction(descriptor_, options_)) { if (ShouldForceAllocationOnConstruction(descriptor_, options_)) {
@ -3159,7 +3159,7 @@ void MessageGenerator::GenerateClear(io::Printer* p) {
GOOGLE_CHECK_EQ(chunk_is_split, ShouldSplit(memset_start, options_)); GOOGLE_CHECK_EQ(chunk_is_split, ShouldSplit(memset_start, options_));
GOOGLE_CHECK_EQ(chunk_is_split, ShouldSplit(memset_end, options_)); GOOGLE_CHECK_EQ(chunk_is_split, ShouldSplit(memset_end, options_));
format( format(
"::memset(&$1$, 0, static_cast<size_t>(\n" "::memset(&$1$, 0, static_cast<::size_t>(\n"
" reinterpret_cast<char*>(&$2$) -\n" " reinterpret_cast<char*>(&$2$) -\n"
" reinterpret_cast<char*>(&$1$)) + sizeof($2$));\n", " reinterpret_cast<char*>(&$1$)) + sizeof($2$));\n",
FieldMemberName(memset_start, chunk_is_split), FieldMemberName(memset_start, chunk_is_split),
@ -3656,7 +3656,7 @@ void MessageGenerator::GenerateCopyFrom(io::Printer* p) {
if (HasDescriptorMethods(descriptor_->file(), options_)) { if (HasDescriptorMethods(descriptor_->file(), options_)) {
format("FailIfCopyFromDescendant(*this, from);\n"); format("FailIfCopyFromDescendant(*this, from);\n");
} else { } else {
format("size_t from_size = from.ByteSizeLong();\n"); format("::size_t from_size = from.ByteSizeLong();\n");
} }
format( format(
"#endif\n" "#endif\n"
@ -4137,10 +4137,10 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) {
if (descriptor_->options().message_set_wire_format()) { if (descriptor_->options().message_set_wire_format()) {
// Special-case MessageSet. // Special-case MessageSet.
format( format(
"size_t $classname$::ByteSizeLong() const {\n" "::size_t $classname$::ByteSizeLong() const {\n"
"$annotate_bytesize$" "$annotate_bytesize$"
"// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
" size_t total_size = $extensions$.MessageSetByteSize();\n" " ::size_t total_size = $extensions$.MessageSetByteSize();\n"
" if ($have_unknown_fields$) {\n" " if ($have_unknown_fields$) {\n"
" total_size += ::_pbi::\n" " total_size += ::_pbi::\n"
" ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n"
@ -4157,11 +4157,11 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) {
// Emit a function (rarely used, we hope) that handles the required fields // Emit a function (rarely used, we hope) that handles the required fields
// by checking for each one individually. // by checking for each one individually.
format( format(
"size_t $classname$::RequiredFieldsByteSizeFallback() const {\n" "::size_t $classname$::RequiredFieldsByteSizeFallback() const {\n"
"// @@protoc_insertion_point(required_fields_byte_size_fallback_start:" "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
"$full_name$)\n"); "$full_name$)\n");
format.Indent(); format.Indent();
format("size_t total_size = 0;\n"); format("::size_t total_size = 0;\n");
for (auto field : optimized_order_) { for (auto field : optimized_order_) {
if (field->is_required()) { if (field->is_required()) {
format( format(
@ -4183,12 +4183,12 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) {
} }
format( format(
"size_t $classname$::ByteSizeLong() const {\n" "::size_t $classname$::ByteSizeLong() const {\n"
"$annotate_bytesize$" "$annotate_bytesize$"
"// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n"); "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n");
format.Indent(); format.Indent();
format( format(
"size_t total_size = 0;\n" "::size_t total_size = 0;\n"
"\n"); "\n");
if (descriptor_->extension_range_count() > 0) { if (descriptor_->extension_range_count() > 0) {

@ -37,8 +37,7 @@
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
#include "google/protobuf/compiler/cpp/field.h" #include "google/protobuf/compiler/cpp/field.h"
#include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/helpers.h"
#include "absl/strings/str_cat.h"
#include "google/protobuf/stubs/strutil.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -32,8 +32,10 @@
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <map>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector>
#include "google/protobuf/wire_format.h" #include "google/protobuf/wire_format.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
@ -59,7 +61,7 @@ bool UseDirectTcParserTable(const FieldDescriptor* field,
return !m->options().message_set_wire_format() && return !m->options().message_set_wire_format() &&
m->file()->options().optimize_for() != FileOptions::CODE_SIZE && m->file()->options().optimize_for() != FileOptions::CODE_SIZE &&
!HasSimpleBaseClass(m, options) && !HasTracker(m, options) !HasSimpleBaseClass(m, options) && !HasTracker(m, options)
; ; // NOLINT(whitespace/semicolon)
} }
std::vector<const FieldDescriptor*> GetOrderedFields( std::vector<const FieldDescriptor*> GetOrderedFields(
@ -215,6 +217,17 @@ void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) {
"}\n\n"); "}\n\n");
} }
static bool NeedsUnknownEnumSupport(const Descriptor* descriptor) {
for (int i = 0; i < descriptor->field_count(); ++i) {
auto* field = descriptor->field(i);
if (field->is_repeated() && field->cpp_type() == field->CPPTYPE_ENUM &&
!internal::cpp::HasPreservingUnknownEnumSemantics(field)) {
return true;
}
}
return false;
}
void ParseFunctionGenerator::GenerateTailcallFallbackFunction( void ParseFunctionGenerator::GenerateTailcallFallbackFunction(
Formatter& format) { Formatter& format) {
GOOGLE_CHECK(should_generate_tctable()); GOOGLE_CHECK(should_generate_tctable());
@ -224,11 +237,27 @@ void ParseFunctionGenerator::GenerateTailcallFallbackFunction(
format.Indent(); format.Indent();
format("auto* typed_msg = static_cast<$classname$*>(msg);\n"); format("auto* typed_msg = static_cast<$classname$*>(msg);\n");
// If we need a side channel, generate the check to jump to the generic
// handler to deal with the side channel data.
if (NeedsUnknownEnumSupport(descriptor_)) {
format(
"if (PROTOBUF_PREDICT_FALSE(\n"
" _pbi::TcParser::MustFallbackToGeneric(PROTOBUF_TC_PARAM_PASS))) "
"{\n"
" PROTOBUF_MUSTTAIL return "
"::_pbi::TcParser::GenericFallback$1$(PROTOBUF_TC_PARAM_PASS);\n"
"}\n",
GetOptimizeFor(descriptor_->file(), options_) ==
FileOptions::LITE_RUNTIME
? "Lite"
: "");
}
if (num_hasbits_ > 0) { if (num_hasbits_ > 0) {
// Sync hasbits // Sync hasbits
format("typed_msg->_impl_._has_bits_[0] |= hasbits;\n"); format("typed_msg->_impl_._has_bits_[0] |= hasbits;\n");
} }
format("uint32_t tag = data.tag();\n"); format("::uint32_t tag = data.tag();\n");
format.Set("msg", "typed_msg->"); format.Set("msg", "typed_msg->");
format.Set("this", "typed_msg"); format.Set("this", "typed_msg");
@ -343,7 +372,7 @@ void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) {
format.Indent(); format.Indent();
format( format(
"uint32_t tag;\n" "::uint32_t tag;\n"
"ptr = ::_pbi::ReadTag(ptr, &tag);\n"); "ptr = ::_pbi::ReadTag(ptr, &tag);\n");
GenerateParseIterationBody(format, descriptor_, ordered_fields_); GenerateParseIterationBody(format, descriptor_, ordered_fields_);
@ -645,8 +674,8 @@ void ParseFunctionGenerator::GenerateFastFieldEntries(Formatter& format) {
absl::EndsWith(func_name, "V64S1")) { absl::EndsWith(func_name, "V64S1")) {
std::string field_type = absl::EndsWith(func_name, "V8S1") ? "bool" std::string field_type = absl::EndsWith(func_name, "V8S1") ? "bool"
: absl::EndsWith(func_name, "V32S1") : absl::EndsWith(func_name, "V32S1")
? "uint32_t" ? "::uint32_t"
: "uint64_t"; : "::uint64_t";
func_name = absl::StrCat( func_name = absl::StrCat(
"::_pbi::TcParser::SingularVarintNoZag1<", field_type, "::_pbi::TcParser::SingularVarintNoZag1<", field_type,
", offsetof(", // ", offsetof(", //
@ -1352,8 +1381,9 @@ void ParseFunctionGenerator::GenerateFieldSwitch(
format.Outdent(); format.Outdent();
} }
format( format(
"} else\n" "} else {\n"
" goto handle_unusual;\n" " goto handle_unusual;\n"
"}\n"
"$next_tag$;\n"); "$next_tag$;\n");
format.Outdent(); format.Outdent();
} // for loop over ordered fields } // for loop over ordered fields
@ -1382,21 +1412,21 @@ void PopulateFastFieldEntry(const Descriptor* descriptor,
">()"); ">()");
} else if (name == "V32S1") { } else if (name == "V32S1") {
info.func_name = absl::StrCat( info.func_name = absl::StrCat(
"::_pbi::TcParser::SingularVarintNoZag1<uint32_t, offsetof(", // "::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(", //
ClassName(descriptor), // ClassName(descriptor), //
", ", // ", ", //
FieldMemberName(field, /*split=*/false), // FieldMemberName(field, /*split=*/false), //
"), ", // "), ", //
HasHasbit(field) ? entry.hasbit_idx : 63, // HasHasbit(field) ? entry.hasbit_idx : 63, //
">()"); ">()");
} else if (name == "V64S1") { } else if (name == "V64S1") {
info.func_name = absl::StrCat( info.func_name = absl::StrCat(
"::_pbi::TcParser::SingularVarintNoZag1<uint64_t, offsetof(", // "::_pbi::TcParser::SingularVarintNoZag1<::uint64_t, offsetof(", //
ClassName(descriptor), // ClassName(descriptor), //
", ", // ", ", //
FieldMemberName(field, /*split=*/false), // FieldMemberName(field, /*split=*/false), //
"), ", // "), ", //
HasHasbit(field) ? entry.hasbit_idx : 63, // HasHasbit(field) ? entry.hasbit_idx : 63, //
">()"); ">()");
} else { } else {
info.func_name = absl::StrCat("::_pbi::TcParser::Fast", name); info.func_name = absl::StrCat("::_pbi::TcParser::Fast", name);

@ -467,13 +467,13 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize(
int fixed_size = FixedSize(descriptor_->type()); int fixed_size = FixedSize(descriptor_->type());
if (fixed_size == -1) { if (fixed_size == -1) {
format( format(
"size_t data_size = ::_pbi::WireFormatLite::\n" "::size_t data_size = ::_pbi::WireFormatLite::\n"
" $declared_type$Size(this->$field$);\n"); " $declared_type$Size(this->$field$);\n");
} else { } else {
format( format(
"unsigned int count = static_cast<unsigned " "unsigned int count = static_cast<unsigned "
"int>(this->_internal_$name$_size());\n" "int>(this->_internal_$name$_size());\n"
"size_t data_size = $fixed_size$UL * count;\n"); "::size_t data_size = $fixed_size$UL * count;\n");
} }
if (descriptor_->is_packed()) { if (descriptor_->is_packed()) {

@ -34,13 +34,10 @@
#include "google/protobuf/compiler/cpp/string_field.h" #include "google/protobuf/compiler/cpp/string_field.h"
#include "google/protobuf/io/printer.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/helpers.h"
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/stubs/strutil.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {
@ -729,7 +726,7 @@ void RepeatedStringFieldGenerator::GenerateAccessorDeclarations(
} }
format( format(
"$deprecated_attr$void ${1$set_$name$$}$(" "$deprecated_attr$void ${1$set_$name$$}$("
"int index, const $pointer_type$* value, size_t size);\n" "int index, const $pointer_type$* value, ::size_t size);\n"
"$deprecated_attr$std::string* ${1$add_$name$$}$();\n" "$deprecated_attr$std::string* ${1$add_$name$$}$();\n"
"$deprecated_attr$void ${1$add_$name$$}$(const std::string& value);\n" "$deprecated_attr$void ${1$add_$name$$}$(const std::string& value);\n"
"$deprecated_attr$void ${1$add_$name$$}$(std::string&& value);\n" "$deprecated_attr$void ${1$add_$name$$}$(std::string&& value);\n"
@ -742,7 +739,7 @@ void RepeatedStringFieldGenerator::GenerateAccessorDeclarations(
} }
format( format(
"$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* " "$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* "
"value, size_t size)" "value, ::size_t size)"
";\n" ";\n"
"$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<std::string>& " "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<std::string>& "
"${1$$name$$}$() " "${1$$name$$}$() "
@ -828,7 +825,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
format( format(
"inline void " "inline void "
"$classname$::set_$name$" "$classname$::set_$name$"
"(int index, const $pointer_type$* value, size_t size) {\n" "(int index, const $pointer_type$* value, ::size_t size) {\n"
" $field$.Mutable(index)->assign(\n" " $field$.Mutable(index)->assign(\n"
" reinterpret_cast<const char*>(value), size);\n" " reinterpret_cast<const char*>(value), size);\n"
"$annotate_set$" "$annotate_set$"
@ -863,7 +860,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
} }
format( format(
"inline void " "inline void "
"$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n" "$classname$::add_$name$(const $pointer_type$* value, ::size_t size) {\n"
" $field$.Add()->assign(reinterpret_cast<const char*>(value), size);\n" " $field$.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
"$annotate_add$" "$annotate_add$"
" // @@protoc_insertion_point(field_add_pointer:$full_name$)\n" " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"

@ -93,11 +93,16 @@ message TestConflictingSymbolNames {
optional int32 already_here = 15; optional int32 already_here = 15;
optional uint32 uint32 = 16; optional uint32 uint32 = 16;
optional uint32 uint32_t = 41;
optional uint64 uint64 = 17; optional uint64 uint64 = 17;
optional uint32 uint64_t = 42;
optional string string = 18; optional string string = 18;
optional int32 memset = 19; optional int32 memset = 19;
optional int32 int32 = 20; optional int32 int32 = 20;
optional int32 int32_t = 43;
optional int64 int64 = 21; optional int64 int64 = 21;
optional int64 int64_t = 44;
optional int64 size_t = 45;
optional uint32 cached_size = 22; optional uint32 cached_size = 22;
optional uint32 extensions = 23; optional uint32 extensions = 23;

@ -34,7 +34,6 @@
#include <string> #include <string>
#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/stubs/strutil.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"

@ -88,7 +88,7 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) { void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) {
printer->Print( printer->Print(
variables_, variables_,
"$name$_.MergeFrom(other.$name$_);\n"); "$name$_.Add(other.$name$_);\n");
} }
void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) { void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) {

@ -46,10 +46,9 @@
#include "google/protobuf/testing/googletest.h" #include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include "google/protobuf/stubs/strutil.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {

@ -37,18 +37,14 @@
#include <memory> #include <memory>
#include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "google/protobuf/compiler/java/file.h" #include "google/protobuf/compiler/java/file.h"
#include "google/protobuf/compiler/java/generator_factory.h"
#include "google/protobuf/compiler/java/helpers.h" #include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/compiler/java/name_resolver.h"
#include "google/protobuf/compiler/java/options.h" #include "google/protobuf/compiler/java/options.h"
#include "google/protobuf/compiler/java/shared_code_generator.h" #include "google/protobuf/compiler/java/shared_code_generator.h"
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/stubs/strutil.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -40,7 +40,6 @@
#include <vector> #include <vector>
#include "google/protobuf/wire_format.h" #include "google/protobuf/wire_format.h"
#include "google/protobuf/stubs/strutil.h"
#include "absl/container/flat_hash_set.h" #include "absl/container/flat_hash_set.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
@ -52,6 +51,7 @@
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/compiler/java/name_resolver.h"
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/strtod.h"
// Must be last. // Must be last.
#include "google/protobuf/port_def.inc" #include "google/protobuf/port_def.inc"
@ -479,7 +479,7 @@ std::string DefaultValue(const FieldDescriptor* field, bool immutable,
} else if (value != value) { } else if (value != value) {
return "Double.NaN"; return "Double.NaN";
} else { } else {
return SimpleDtoa(value) + "D"; return io::SimpleDtoa(value) + "D";
} }
} }
case FieldDescriptor::CPPTYPE_FLOAT: { case FieldDescriptor::CPPTYPE_FLOAT: {
@ -491,7 +491,7 @@ std::string DefaultValue(const FieldDescriptor* field, bool immutable,
} else if (value != value) { } else if (value != value) {
return "Float.NaN"; return "Float.NaN";
} else { } else {
return SimpleFtoa(value) + "F"; return io::SimpleFtoa(value) + "F";
} }
} }
case FieldDescriptor::CPPTYPE_BOOL: case FieldDescriptor::CPPTYPE_BOOL:

@ -33,6 +33,7 @@ cc_library(
":line_consumer", ":line_consumer",
"//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf:protobuf_nowkt",
"@com_google_absl//absl/container:flat_hash_set",
], ],
) )

@ -31,7 +31,9 @@
#include "google/protobuf/compiler/objectivec/enum.h" #include "google/protobuf/compiler/objectivec/enum.h"
#include <algorithm> #include <algorithm>
#include <limits>
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
@ -90,8 +92,6 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
} }
} }
EnumGenerator::~EnumGenerator() {}
void EnumGenerator::GenerateHeader(io::Printer* printer) { void EnumGenerator::GenerateHeader(io::Printer* printer) {
std::string enum_comments; std::string enum_comments;
SourceLocation location; SourceLocation location;
@ -151,7 +151,7 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
if (i > 0) { if (i > 0) {
printer->Print("\n"); printer->Print("\n");
} }
printer->Print(comments.c_str()); printer->Print(comments);
} }
} }

@ -46,7 +46,7 @@ namespace objectivec {
class EnumGenerator { class EnumGenerator {
public: public:
explicit EnumGenerator(const EnumDescriptor* descriptor); explicit EnumGenerator(const EnumDescriptor* descriptor);
~EnumGenerator(); ~EnumGenerator() = default;
EnumGenerator(const EnumGenerator&) = delete; EnumGenerator(const EnumGenerator&) = delete;
EnumGenerator& operator=(const EnumGenerator&) = delete; EnumGenerator& operator=(const EnumGenerator&) = delete;

@ -31,6 +31,7 @@
#include "google/protobuf/compiler/objectivec/enum_field.h" #include "google/protobuf/compiler/objectivec/enum_field.h"
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/helpers.h"
@ -71,8 +72,6 @@ EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor)
SetEnumVariables(descriptor, &variables_); SetEnumVariables(descriptor, &variables_);
} }
EnumFieldGenerator::~EnumFieldGenerator() {}
void EnumFieldGenerator::GenerateCFunctionDeclarations( void EnumFieldGenerator::GenerateCFunctionDeclarations(
io::Printer* printer) const { io::Printer* printer) const {
if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
@ -142,9 +141,7 @@ RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
variables_["array_storage_type"] = "GPBEnumArray"; variables_["array_storage_type"] = "GPBEnumArray";
} }
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} void RepeatedEnumFieldGenerator::FinishInitialization() {
void RepeatedEnumFieldGenerator::FinishInitialization(void) {
RepeatedFieldGenerator::FinishInitialization(); RepeatedFieldGenerator::FinishInitialization();
variables_["array_comment"] = "// |" + variables_["name"] + "| contains |" + variables_["array_comment"] = "// |" + variables_["name"] + "| contains |" +
variables_["storage_type"] + "|\n"; variables_["storage_type"] + "|\n";

@ -32,6 +32,7 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include "google/protobuf/compiler/objectivec/field.h" #include "google/protobuf/compiler/objectivec/field.h"
@ -48,28 +49,25 @@ class EnumFieldGenerator : public SingleFieldGenerator {
EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete;
public: public:
virtual void GenerateCFunctionDeclarations( void GenerateCFunctionDeclarations(io::Printer* printer) const override;
io::Printer* printer) const override; void GenerateCFunctionImplementations(io::Printer* printer) const override;
virtual void GenerateCFunctionImplementations( void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
io::Printer* printer) const override; bool include_external_types) const override;
virtual void DetermineForwardDeclarations(
std::set<std::string>* fwd_decls,
bool include_external_types) const override;
protected: protected:
explicit EnumFieldGenerator(const FieldDescriptor* descriptor); explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
virtual ~EnumFieldGenerator(); ~EnumFieldGenerator() override = default;
}; };
class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator {
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
public: public:
virtual void FinishInitialization() override; void FinishInitialization() override;
protected: protected:
explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
virtual ~RepeatedEnumFieldGenerator(); ~RepeatedEnumFieldGenerator() override = default;
}; };
} // namespace objectivec } // namespace objectivec

@ -31,6 +31,11 @@
#include "google/protobuf/compiler/objectivec/extension.h" #include "google/protobuf/compiler/objectivec/extension.h"
#include <iostream> #include <iostream>
#include <map>
#include <ostream>
#include <set>
#include <string>
#include <vector>
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/helpers.h"
@ -58,8 +63,6 @@ ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name,
} }
} }
ExtensionGenerator::~ExtensionGenerator() {}
void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
vars["method_name"] = method_name_; vars["method_name"] = method_name_;

@ -31,6 +31,8 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
#include <string>
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
@ -43,7 +45,7 @@ class ExtensionGenerator {
public: public:
ExtensionGenerator(const std::string& root_class_name, ExtensionGenerator(const std::string& root_class_name,
const FieldDescriptor* descriptor); const FieldDescriptor* descriptor);
~ExtensionGenerator(); ~ExtensionGenerator() = default;
ExtensionGenerator(const ExtensionGenerator&) = delete; ExtensionGenerator(const ExtensionGenerator&) = delete;
ExtensionGenerator& operator=(const ExtensionGenerator&) = delete; ExtensionGenerator& operator=(const ExtensionGenerator&) = delete;

@ -31,6 +31,11 @@
#include "google/protobuf/compiler/objectivec/field.h" #include "google/protobuf/compiler/objectivec/field.h"
#include <iostream> #include <iostream>
#include <map>
#include <ostream>
#include <set>
#include <string>
#include <vector>
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "google/protobuf/compiler/objectivec/enum_field.h" #include "google/protobuf/compiler/objectivec/enum_field.h"
@ -166,7 +171,7 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
} // namespace } // namespace
FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
FieldGenerator* result = NULL; FieldGenerator* result = nullptr;
if (field->is_repeated()) { if (field->is_repeated()) {
switch (GetObjectiveCType(field)) { switch (GetObjectiveCType(field)) {
case OBJECTIVECTYPE_MESSAGE: { case OBJECTIVECTYPE_MESSAGE: {
@ -211,8 +216,6 @@ FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor)
SetCommonFieldVariables(descriptor, &variables_); SetCommonFieldVariables(descriptor, &variables_);
} }
FieldGenerator::~FieldGenerator() {}
void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const { void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const {
printer->Print(variables_, "$field_number_name$ = $field_number$,\n"); printer->Print(variables_, "$field_number_name$ = $field_number$,\n");
} }
@ -275,11 +278,9 @@ void FieldGenerator::SetRuntimeHasBit(int has_index) {
variables_["has_index"] = absl::StrCat(has_index); variables_["has_index"] = absl::StrCat(has_index);
} }
void FieldGenerator::SetNoHasBit(void) { void FieldGenerator::SetNoHasBit() { variables_["has_index"] = "GPBNoHasBit"; }
variables_["has_index"] = "GPBNoHasBit";
}
int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const { return 0; } int FieldGenerator::ExtraRuntimeHasBitsNeeded() const { return 0; }
void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) { void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
@ -292,18 +293,18 @@ void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
void FieldGenerator::SetOneofIndexBase(int index_base) { void FieldGenerator::SetOneofIndexBase(int index_base) {
const OneofDescriptor* oneof = descriptor_->real_containing_oneof(); const OneofDescriptor* oneof = descriptor_->real_containing_oneof();
if (oneof != NULL) { if (oneof != nullptr) {
int index = oneof->index() + index_base; int index = oneof->index() + index_base;
// Flip the sign to mark it as a oneof. // Flip the sign to mark it as a oneof.
variables_["has_index"] = absl::StrCat(-index); variables_["has_index"] = absl::StrCat(-index);
} }
} }
bool FieldGenerator::WantsHasProperty(void) const { bool FieldGenerator::WantsHasProperty() const {
return descriptor_->has_presence() && !descriptor_->real_containing_oneof(); return descriptor_->has_presence() && !descriptor_->real_containing_oneof();
} }
void FieldGenerator::FinishInitialization(void) { void FieldGenerator::FinishInitialization() {
// If "property_type" wasn't set, make it "storage_type". // If "property_type" wasn't set, make it "storage_type".
if ((variables_.find("property_type") == variables_.end()) && if ((variables_.find("property_type") == variables_.end()) &&
(variables_.find("storage_type") != variables_.end())) { (variables_.find("storage_type") != variables_.end())) {
@ -316,8 +317,6 @@ SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor)
// Nothing // Nothing
} }
SingleFieldGenerator::~SingleFieldGenerator() {}
void SingleFieldGenerator::GenerateFieldStorageDeclaration( void SingleFieldGenerator::GenerateFieldStorageDeclaration(
io::Printer* printer) const { io::Printer* printer) const {
printer->Print(variables_, "$storage_type$ $name$;\n"); printer->Print(variables_, "$storage_type$ $name$;\n");
@ -350,7 +349,7 @@ void SingleFieldGenerator::GeneratePropertyImplementation(
} }
} }
bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { bool SingleFieldGenerator::RuntimeUsesHasBit() const {
if (descriptor_->real_containing_oneof()) { if (descriptor_->real_containing_oneof()) {
// The oneof tracks what is set instead. // The oneof tracks what is set instead.
return false; return false;
@ -366,8 +365,6 @@ ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor)
} }
} }
ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {}
void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration( void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
io::Printer* printer) const { io::Printer* printer) const {
printer->Print(variables_, "$storage_type$ *$name$;\n"); printer->Print(variables_, "$storage_type$ *$name$;\n");
@ -410,9 +407,7 @@ RepeatedFieldGenerator::RepeatedFieldGenerator(
variables_["array_comment"] = ""; variables_["array_comment"] = "";
} }
RepeatedFieldGenerator::~RepeatedFieldGenerator() {} void RepeatedFieldGenerator::FinishInitialization() {
void RepeatedFieldGenerator::FinishInitialization(void) {
FieldGenerator::FinishInitialization(); FieldGenerator::FinishInitialization();
if (variables_.find("array_property_type") == variables_.end()) { if (variables_.find("array_property_type") == variables_.end()) {
variables_["array_property_type"] = variable("array_storage_type"); variables_["array_property_type"] = variable("array_storage_type");
@ -457,7 +452,7 @@ void RepeatedFieldGenerator::GeneratePropertyDeclaration(
printer->Print("\n"); printer->Print("\n");
} }
bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { bool RepeatedFieldGenerator::RuntimeUsesHasBit() const {
return false; // The array (or map/dict) having anything is what is used. return false; // The array (or map/dict) having anything is what is used.
} }
@ -475,8 +470,6 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
} }
} }
FieldGeneratorMap::~FieldGeneratorMap() {}
const FieldGenerator& FieldGeneratorMap::get( const FieldGenerator& FieldGeneratorMap::get(
const FieldDescriptor* field) const { const FieldDescriptor* field) const {
GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
@ -487,7 +480,7 @@ const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
return *extension_generators_[index]; return *extension_generators_[index];
} }
int FieldGeneratorMap::CalculateHasBits(void) { int FieldGeneratorMap::CalculateHasBits() {
int total_bits = 0; int total_bits = 0;
for (int i = 0; i < descriptor_->field_count(); i++) { for (int i = 0; i < descriptor_->field_count(); i++) {
if (field_generators_[i]->RuntimeUsesHasBit()) { if (field_generators_[i]->RuntimeUsesHasBit()) {
@ -511,7 +504,7 @@ void FieldGeneratorMap::SetOneofIndexBase(int index_base) {
} }
} }
bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault(void) const { bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault() const {
for (int i = 0; i < descriptor_->field_count(); i++) { for (int i = 0; i < descriptor_->field_count(); i++) {
if (HasNonZeroDefaultValue(descriptor_->field(i))) { if (HasNonZeroDefaultValue(descriptor_->field(i))) {
return true; return true;

@ -32,8 +32,12 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
#include <map> #include <map>
#include <memory>
#include <set>
#include <string> #include <string>
#include <vector>
#include "absl/strings/match.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
@ -46,7 +50,7 @@ class FieldGenerator {
public: public:
static FieldGenerator* Make(const FieldDescriptor* field); static FieldGenerator* Make(const FieldDescriptor* field);
virtual ~FieldGenerator(); virtual ~FieldGenerator() = default;
FieldGenerator(const FieldGenerator&) = delete; FieldGenerator(const FieldGenerator&) = delete;
FieldGenerator& operator=(const FieldGenerator&) = delete; FieldGenerator& operator=(const FieldGenerator&) = delete;
@ -75,10 +79,10 @@ class FieldGenerator {
void GenerateFieldNumberConstant(io::Printer* printer) const; void GenerateFieldNumberConstant(io::Printer* printer) const;
// Exposed to get and set the has bits information. // Exposed to get and set the has bits information.
virtual bool RuntimeUsesHasBit(void) const = 0; virtual bool RuntimeUsesHasBit() const = 0;
void SetRuntimeHasBit(int has_index); void SetRuntimeHasBit(int has_index);
void SetNoHasBit(void); void SetNoHasBit();
virtual int ExtraRuntimeHasBitsNeeded(void) const; virtual int ExtraRuntimeHasBitsNeeded() const;
virtual void SetExtraRuntimeHasBitsBase(int index_base); virtual void SetExtraRuntimeHasBitsBase(int index_base);
void SetOneofIndexBase(int index_base); void SetOneofIndexBase(int index_base);
@ -88,8 +92,7 @@ class FieldGenerator {
bool needs_textformat_name_support() const { bool needs_textformat_name_support() const {
const std::string& field_flags = variable("fieldflags"); const std::string& field_flags = variable("fieldflags");
return field_flags.find("GPBFieldTextFormatNameCustom") != return absl::StrContains(field_flags, "GPBFieldTextFormatNameCustom");
std::string::npos;
} }
std::string generated_objc_name() const { return variable("name"); } std::string generated_objc_name() const { return variable("name"); }
std::string raw_field_name() const { return variable("raw_field_name"); } std::string raw_field_name() const { return variable("raw_field_name"); }
@ -97,8 +100,8 @@ class FieldGenerator {
protected: protected:
explicit FieldGenerator(const FieldDescriptor* descriptor); explicit FieldGenerator(const FieldDescriptor* descriptor);
virtual void FinishInitialization(void); virtual void FinishInitialization();
bool WantsHasProperty(void) const; bool WantsHasProperty() const;
const FieldDescriptor* descriptor_; const FieldDescriptor* descriptor_;
std::map<std::string, std::string> variables_; std::map<std::string, std::string> variables_;
@ -106,19 +109,17 @@ class FieldGenerator {
class SingleFieldGenerator : public FieldGenerator { class SingleFieldGenerator : public FieldGenerator {
public: public:
virtual ~SingleFieldGenerator(); ~SingleFieldGenerator() override = default;
SingleFieldGenerator(const SingleFieldGenerator&) = delete; SingleFieldGenerator(const SingleFieldGenerator&) = delete;
SingleFieldGenerator& operator=(const SingleFieldGenerator&) = delete; SingleFieldGenerator& operator=(const SingleFieldGenerator&) = delete;
virtual void GenerateFieldStorageDeclaration( void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
io::Printer* printer) const override; void GeneratePropertyDeclaration(io::Printer* printer) const override;
virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
virtual void GeneratePropertyImplementation( void GeneratePropertyImplementation(io::Printer* printer) const override;
io::Printer* printer) const override;
virtual bool RuntimeUsesHasBit(void) const override; bool RuntimeUsesHasBit() const override;
protected: protected:
explicit SingleFieldGenerator(const FieldDescriptor* descriptor); explicit SingleFieldGenerator(const FieldDescriptor* descriptor);
@ -127,14 +128,13 @@ class SingleFieldGenerator : public FieldGenerator {
// Subclass with common support for when the field ends up as an ObjC Object. // Subclass with common support for when the field ends up as an ObjC Object.
class ObjCObjFieldGenerator : public SingleFieldGenerator { class ObjCObjFieldGenerator : public SingleFieldGenerator {
public: public:
virtual ~ObjCObjFieldGenerator(); ~ObjCObjFieldGenerator() override = default;
ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete; ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete;
ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete; ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete;
virtual void GenerateFieldStorageDeclaration( void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
io::Printer* printer) const override; void GeneratePropertyDeclaration(io::Printer* printer) const override;
virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
protected: protected:
explicit ObjCObjFieldGenerator(const FieldDescriptor* descriptor); explicit ObjCObjFieldGenerator(const FieldDescriptor* descriptor);
@ -142,30 +142,28 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator {
class RepeatedFieldGenerator : public ObjCObjFieldGenerator { class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
public: public:
virtual ~RepeatedFieldGenerator(); ~RepeatedFieldGenerator() override = default;
RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete; RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete;
RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete; RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete;
virtual void GenerateFieldStorageDeclaration( void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
io::Printer* printer) const override; void GeneratePropertyDeclaration(io::Printer* printer) const override;
virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
virtual void GeneratePropertyImplementation( void GeneratePropertyImplementation(io::Printer* printer) const override;
io::Printer* printer) const override;
virtual bool RuntimeUsesHasBit(void) const override; bool RuntimeUsesHasBit() const override;
protected: protected:
explicit RepeatedFieldGenerator(const FieldDescriptor* descriptor); explicit RepeatedFieldGenerator(const FieldDescriptor* descriptor);
virtual void FinishInitialization(void) override; void FinishInitialization() override;
}; };
// Convenience class which constructs FieldGenerators for a Descriptor. // Convenience class which constructs FieldGenerators for a Descriptor.
class FieldGeneratorMap { class FieldGeneratorMap {
public: public:
explicit FieldGeneratorMap(const Descriptor* descriptor); explicit FieldGeneratorMap(const Descriptor* descriptor);
~FieldGeneratorMap(); ~FieldGeneratorMap() = default;
FieldGeneratorMap(const FieldGeneratorMap&) = delete; FieldGeneratorMap(const FieldGeneratorMap&) = delete;
FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete; FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete;
@ -174,12 +172,12 @@ class FieldGeneratorMap {
const FieldGenerator& get_extension(int index) const; const FieldGenerator& get_extension(int index) const;
// Assigns the has bits and returns the number of bits needed. // Assigns the has bits and returns the number of bits needed.
int CalculateHasBits(void); int CalculateHasBits();
void SetOneofIndexBase(int index_base); void SetOneofIndexBase(int index_base);
// Check if any field of this message has a non zero default. // Check if any field of this message has a non zero default.
bool DoesAnyFieldHaveNonZeroDefault(void) const; bool DoesAnyFieldHaveNonZeroDefault() const;
private: private:
const Descriptor* descriptor_; const Descriptor* descriptor_;

@ -32,13 +32,18 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <iterator>
#include <map>
#include <set>
#include <sstream> #include <sstream>
#include <string>
#include <vector>
#include "absl/strings/str_cat.h"
#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/code_generator.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_cat.h"
#include "google/protobuf/compiler/objectivec/enum.h" #include "google/protobuf/compiler/objectivec/enum.h"
#include "google/protobuf/compiler/objectivec/extension.h" #include "google/protobuf/compiler/objectivec/extension.h"
#include "google/protobuf/compiler/objectivec/helpers.h"
#include "google/protobuf/compiler/objectivec/import_writer.h" #include "google/protobuf/compiler/objectivec/import_writer.h"
#include "google/protobuf/compiler/objectivec/message.h" #include "google/protobuf/compiler/objectivec/message.h"
#include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/compiler/objectivec/names.h"
@ -137,19 +142,17 @@ struct FileDescriptorsOrderedByName {
} // namespace } // namespace
FileGenerator::CommonState::CommonState() {}
const FileGenerator::CommonState::MinDepsEntry& const FileGenerator::CommonState::MinDepsEntry&
FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal( FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal(
const FileDescriptor* file) { const FileDescriptor* file) {
auto it = deps_info_cache_.find(file); auto it = deps_info_cache.find(file);
if (it != deps_info_cache_.end()) { if (it != deps_info_cache.end()) {
return it->second; return it->second;
} }
std::unordered_set<const FileDescriptor*> min_deps_collector; absl::flat_hash_set<const FileDescriptor*> min_deps_collector;
std::unordered_set<const FileDescriptor*> covered_deps_collector; absl::flat_hash_set<const FileDescriptor*> covered_deps_collector;
std::unordered_set<const FileDescriptor*> to_prune; absl::flat_hash_set<const FileDescriptor*> to_prune;
for (int i = 0; i < file->dependency_count(); i++) { for (int i = 0; i < file->dependency_count(); i++) {
const FileDescriptor* dep = file->dependency(i); const FileDescriptor* dep = file->dependency(i);
MinDepsEntry dep_info = MinDepsEntry dep_info =
@ -182,19 +185,19 @@ FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal(
// Fast path: if nothing to prune or there was only one dep, the prune work is // Fast path: if nothing to prune or there was only one dep, the prune work is
// a waste, skip it. // a waste, skip it.
if (to_prune.empty() || file->dependency_count() == 1) { if (to_prune.empty() || file->dependency_count() == 1) {
return deps_info_cache_ return deps_info_cache
.insert( .insert(
{file, {file_has_exts, min_deps_collector, covered_deps_collector}}) {file, {file_has_exts, min_deps_collector, covered_deps_collector}})
.first->second; .first->second;
} }
std::unordered_set<const FileDescriptor*> min_deps; absl::flat_hash_set<const FileDescriptor*> min_deps;
std::copy_if(min_deps_collector.begin(), min_deps_collector.end(), std::copy_if(min_deps_collector.begin(), min_deps_collector.end(),
std::inserter(min_deps, min_deps.end()), std::inserter(min_deps, min_deps.end()),
[&](const FileDescriptor* value) { [&](const FileDescriptor* value) {
return to_prune.find(value) == to_prune.end(); return to_prune.find(value) == to_prune.end();
}); });
return deps_info_cache_ return deps_info_cache
.insert({file, {file_has_exts, min_deps, covered_deps_collector}}) .insert({file, {file_has_exts, min_deps, covered_deps_collector}})
.first->second; .first->second;
} }
@ -211,7 +214,7 @@ FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal(
const std::vector<const FileDescriptor*> const std::vector<const FileDescriptor*>
FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensions( FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensions(
const FileDescriptor* file) { const FileDescriptor* file) {
std::unordered_set<const FileDescriptor*> min_deps = absl::flat_hash_set<const FileDescriptor*> min_deps =
CollectMinimalFileDepsContainingExtensionsInternal(file).min_deps; CollectMinimalFileDepsContainingExtensionsInternal(file).min_deps;
// Sort the list since pointer order isn't stable across runs. // Sort the list since pointer order isn't stable across runs.
std::vector<const FileDescriptor*> result(min_deps.begin(), min_deps.end()); std::vector<const FileDescriptor*> result(min_deps.begin(), min_deps.end());
@ -243,8 +246,6 @@ FileGenerator::FileGenerator(const FileDescriptor* file,
} }
} }
FileGenerator::~FileGenerator() {}
void FileGenerator::GenerateHeader(io::Printer* printer) { void FileGenerator::GenerateHeader(io::Printer* printer) {
std::vector<std::string> headers; std::vector<std::string> headers;
// Generated files bundled with the library get minimal imports, everything // Generated files bundled with the library get minimal imports, everything

@ -31,11 +31,15 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
#include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "google/protobuf/compiler/objectivec/enum.h"
#include "google/protobuf/compiler/objectivec/extension.h"
#include "google/protobuf/compiler/objectivec/message.h"
#include "google/protobuf/compiler/objectivec/options.h" #include "google/protobuf/compiler/objectivec/options.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
@ -45,16 +49,12 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace objectivec { namespace objectivec {
class EnumGenerator;
class ExtensionGenerator;
class MessageGenerator;
class FileGenerator { class FileGenerator {
public: public:
// Wrapper for some common state that is shared between file generations to // Wrapper for some common state that is shared between file generations to
// improve performance when more than one file is generated at a time. // improve performance when more than one file is generated at a time.
struct CommonState { struct CommonState {
CommonState(); CommonState() = default;
const std::vector<const FileDescriptor*> const std::vector<const FileDescriptor*>
CollectMinimalFileDepsContainingExtensions(const FileDescriptor* file); CollectMinimalFileDepsContainingExtensions(const FileDescriptor* file);
@ -62,20 +62,20 @@ class FileGenerator {
private: private:
struct MinDepsEntry { struct MinDepsEntry {
bool has_extensions; bool has_extensions;
std::unordered_set<const FileDescriptor*> min_deps; absl::flat_hash_set<const FileDescriptor*> min_deps;
// `covered_deps` are the transtive deps of `min_deps_w_exts` that also // `covered_deps` are the transtive deps of `min_deps_w_exts` that also
// have extensions. // have extensions.
std::unordered_set<const FileDescriptor*> covered_deps; absl::flat_hash_set<const FileDescriptor*> covered_deps;
}; };
const MinDepsEntry& CollectMinimalFileDepsContainingExtensionsInternal( const MinDepsEntry& CollectMinimalFileDepsContainingExtensionsInternal(
const FileDescriptor* file); const FileDescriptor* file);
std::unordered_map<const FileDescriptor*, MinDepsEntry> deps_info_cache_; absl::flat_hash_map<const FileDescriptor*, MinDepsEntry> deps_info_cache;
}; };
FileGenerator(const FileDescriptor* file, FileGenerator(const FileDescriptor* file,
const GenerationOptions& generation_options, const GenerationOptions& generation_options,
CommonState& common_state); CommonState& common_state);
~FileGenerator(); ~FileGenerator() = default;
FileGenerator(const FileGenerator&) = delete; FileGenerator(const FileGenerator&) = delete;
FileGenerator& operator=(const FileGenerator&) = delete; FileGenerator& operator=(const FileGenerator&) = delete;

@ -32,14 +32,16 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <memory>
#include <string> #include <string>
#include <unordered_set> #include <utility>
#include <vector>
#include "absl/container/flat_hash_set.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "absl/strings/strip.h" #include "absl/strings/strip.h"
#include "google/protobuf/compiler/objectivec/file.h" #include "google/protobuf/compiler/objectivec/file.h"
#include "google/protobuf/compiler/objectivec/helpers.h"
#include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h" #include "google/protobuf/io/zero_copy_stream.h"
@ -71,10 +73,6 @@ bool StringToBool(const std::string& value, bool* result) {
} // namespace } // namespace
ObjectiveCGenerator::ObjectiveCGenerator() {}
ObjectiveCGenerator::~ObjectiveCGenerator() {}
bool ObjectiveCGenerator::HasGenerateAll() const { return true; } bool ObjectiveCGenerator::HasGenerateAll() const { return true; }
bool ObjectiveCGenerator::Generate(const FileDescriptor* file, bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
@ -127,7 +125,7 @@ bool ObjectiveCGenerator::GenerateAll(
// exclude from the package prefix validations (expected_prefixes_path). // exclude from the package prefix validations (expected_prefixes_path).
// This is provided as an "out", to skip some files being checked. // This is provided as an "out", to skip some files being checked.
for (absl::string_view split_piece : for (absl::string_view split_piece :
absl::StrSplit(options[i].second, ";", absl::SkipEmpty())) { absl::StrSplit(options[i].second, ';', absl::SkipEmpty())) {
validation_options.expected_prefixes_suppressions.push_back( validation_options.expected_prefixes_suppressions.push_back(
std::string(split_piece)); std::string(split_piece));
} }
@ -261,9 +259,9 @@ bool ObjectiveCGenerator::GenerateAll(
// These are not official generation options and could be removed/changed in // These are not official generation options and could be removed/changed in
// the future and doing that won't count as a breaking change. // the future and doing that won't count as a breaking change.
bool headers_only = getenv("GPB_OBJC_HEADERS_ONLY") != NULL; bool headers_only = getenv("GPB_OBJC_HEADERS_ONLY") != nullptr;
std::unordered_set<std::string> skip_impls; absl::flat_hash_set<std::string> skip_impls;
if (getenv("GPB_OBJC_SKIP_IMPLS_FILE") != NULL) { if (getenv("GPB_OBJC_SKIP_IMPLS_FILE") != nullptr) {
std::ifstream skip_file(getenv("GPB_OBJC_SKIP_IMPLS_FILE")); std::ifstream skip_file(getenv("GPB_OBJC_SKIP_IMPLS_FILE"));
if (skip_file.is_open()) { if (skip_file.is_open()) {
std::string line; std::string line;

@ -34,6 +34,7 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
#include <string> #include <string>
#include <vector>
#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
@ -52,8 +53,8 @@ namespace objectivec {
// CodeGenerator with the CommandLineInterface in your main() function. // CodeGenerator with the CommandLineInterface in your main() function.
class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
public: public:
ObjectiveCGenerator(); ObjectiveCGenerator() = default;
~ObjectiveCGenerator(); ~ObjectiveCGenerator() override = default;
ObjectiveCGenerator(const ObjectiveCGenerator&) = delete; ObjectiveCGenerator(const ObjectiveCGenerator&) = delete;
ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete; ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete;

@ -30,15 +30,18 @@
#include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/helpers.h"
#include <string>
#include <vector>
#include "google/protobuf/compiler/code_generator.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
#include "absl/strings/str_split.h" #include "absl/strings/match.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "google/protobuf/compiler/code_generator.h" #include "absl/strings/str_split.h"
#include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/strtod.h"
#include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/stubs/common.h"
#include "google/protobuf/stubs/strutil.h"
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// error cases, so it seems to be ok to use as a back door for errors. // error cases, so it seems to be ok to use as a back door for errors.
@ -91,9 +94,9 @@ std::string HandleExtremeFloatingPoint(std::string val, bool add_float_suffix) {
return "-INFINITY"; return "-INFINITY";
} else { } else {
// float strings with ., e or E need to have f appended // float strings with ., e or E need to have f appended
if (add_float_suffix && (val.find('.') != std::string::npos || if (add_float_suffix &&
val.find('e') != std::string::npos || (absl::StrContains(val, '.') || absl::StrContains(val, 'e') ||
val.find('E') != std::string::npos)) { absl::StrContains(val, 'E'))) {
val += "f"; val += "f";
} }
return val; return val;
@ -263,10 +266,10 @@ std::string DefaultValue(const FieldDescriptor* field) {
return absl::StrCat(field->default_value_uint64()) + "ULL"; return absl::StrCat(field->default_value_uint64()) + "ULL";
case FieldDescriptor::CPPTYPE_DOUBLE: case FieldDescriptor::CPPTYPE_DOUBLE:
return HandleExtremeFloatingPoint( return HandleExtremeFloatingPoint(
SimpleDtoa(field->default_value_double()), false); io::SimpleDtoa(field->default_value_double()), false);
case FieldDescriptor::CPPTYPE_FLOAT: case FieldDescriptor::CPPTYPE_FLOAT:
return HandleExtremeFloatingPoint( return HandleExtremeFloatingPoint(
SimpleFtoa(field->default_value_float()), true); io::SimpleFtoa(field->default_value_float()), true);
case FieldDescriptor::CPPTYPE_BOOL: case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() ? "YES" : "NO"; return field->default_value_bool() ? "YES" : "NO";
case FieldDescriptor::CPPTYPE_STRING: { case FieldDescriptor::CPPTYPE_STRING: {
@ -339,7 +342,7 @@ std::string BuildCommentsString(const SourceLocation& location,
? location.trailing_comments ? location.trailing_comments
: location.leading_comments; : location.leading_comments;
std::vector<std::string> lines; std::vector<std::string> lines;
lines = absl::StrSplit(comments, "\n", absl::AllowEmpty()); lines = absl::StrSplit(comments, '\n', absl::AllowEmpty());
while (!lines.empty() && lines.back().empty()) { while (!lines.empty() && lines.back().empty()) {
lines.pop_back(); lines.pop_back();
} }

@ -122,7 +122,7 @@ std::string BuildCommentsString(const SourceLocation& location,
template <class TDescriptor> template <class TDescriptor>
std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
const FileDescriptor* file = NULL, const FileDescriptor* file = nullptr,
bool preSpace = true, bool preSpace = true,
bool postNewline = false) { bool postNewline = false) {
bool isDeprecated = descriptor->options().deprecated(); bool isDeprecated = descriptor->options().deprecated();

@ -30,7 +30,14 @@
#include "google/protobuf/compiler/objectivec/import_writer.h" #include "google/protobuf/compiler/objectivec/import_writer.h"
#include <iostream>
#include <map>
#include <ostream>
#include <string>
#include <vector>
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "google/protobuf/compiler/objectivec/line_consumer.h" #include "google/protobuf/compiler/objectivec/line_consumer.h"
#include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
@ -47,18 +54,17 @@ namespace {
class ProtoFrameworkCollector : public LineConsumer { class ProtoFrameworkCollector : public LineConsumer {
public: public:
ProtoFrameworkCollector( explicit ProtoFrameworkCollector(
std::map<std::string, std::string>* inout_proto_file_to_framework_name) std::map<std::string, std::string>* inout_proto_file_to_framework_name)
: map_(inout_proto_file_to_framework_name) {} : map_(inout_proto_file_to_framework_name) {}
virtual bool ConsumeLine(const absl::string_view& line, bool ConsumeLine(absl::string_view line, std::string* out_error) override;
std::string* out_error) override;
private: private:
std::map<std::string, std::string>* map_; std::map<std::string, std::string>* map_;
}; };
bool ProtoFrameworkCollector::ConsumeLine(const absl::string_view& line, bool ProtoFrameworkCollector::ConsumeLine(absl::string_view line,
std::string* out_error) { std::string* out_error) {
int offset = line.find(':'); int offset = line.find(':');
if (offset == absl::string_view::npos) { if (offset == absl::string_view::npos) {
@ -93,7 +99,7 @@ bool ProtoFrameworkCollector::ConsumeLine(const absl::string_view& line,
std::cerr.flush(); std::cerr.flush();
} }
if (proto_file.find(' ') != absl::string_view::npos) { if (absl::StrContains(proto_file, ' ')) {
std::cerr << "note: framework mapping file had a proto file with a " std::cerr << "note: framework mapping file had a proto file with a "
"space in, hopefully that isn't a missing comma: '" "space in, hopefully that isn't a missing comma: '"
<< std::string(proto_file) << "'" << std::endl; << std::string(proto_file) << "'" << std::endl;
@ -122,8 +128,6 @@ ImportWriter::ImportWriter(
include_wkt_imports_(include_wkt_imports), include_wkt_imports_(include_wkt_imports),
need_to_parse_mapping_file_(true) {} need_to_parse_mapping_file_(true) {}
ImportWriter::~ImportWriter() {}
void ImportWriter::AddFile(const FileDescriptor* file, void ImportWriter::AddFile(const FileDescriptor* file,
const std::string& header_extension) { const std::string& header_extension) {
if (IsProtobufLibraryBundledProtoFile(file)) { if (IsProtobufLibraryBundledProtoFile(file)) {

@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_IMPORT_WRITER_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_IMPORT_WRITER_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_IMPORT_WRITER_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_IMPORT_WRITER_H__
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
@ -50,7 +51,7 @@ class ImportWriter {
const std::string& named_framework_to_proto_path_mappings_path, const std::string& named_framework_to_proto_path_mappings_path,
const std::string& runtime_import_prefix, const std::string& runtime_import_prefix,
bool include_wkt_imports); bool include_wkt_imports);
~ImportWriter(); ~ImportWriter() = default;
void AddFile(const FileDescriptor* file, const std::string& header_extension); void AddFile(const FileDescriptor* file, const std::string& header_extension);
void Print(io::Printer* printer) const; void Print(io::Printer* printer) const;

@ -39,15 +39,18 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string>
#include <vector> #include <vector>
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "google/protobuf/compiler/objectivec/line_consumer.h" #include "google/protobuf/compiler/objectivec/line_consumer.h"
#include "google/protobuf/io/io_win32.h"
#include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/io/zero_copy_stream_impl.h"
#ifdef _WIN32
#include "google/protobuf/io/io_win32.h"
#endif
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// error cases, so it seems to be ok to use as a back door for errors. // error cases, so it seems to be ok to use as a back door for errors.
@ -91,7 +94,7 @@ void RemoveComment(absl::string_view* input) {
class Parser { class Parser {
public: public:
Parser(LineConsumer* line_consumer) explicit Parser(LineConsumer* line_consumer)
: line_consumer_(line_consumer), line_(0) {} : line_consumer_(line_consumer), line_(0) {}
// Feeds in some input, parse what it can, returning success/failure. Calling // Feeds in some input, parse what it can, returning success/failure. Calling
@ -156,18 +159,8 @@ bool Parser::Finish(std::string* out_error) {
return true; return true;
} }
std::string FullErrorString(const std::string& name, int line_num,
const std::string& msg) {
return std::string("error: ") + name + " Line " + absl::StrCat(line_num) +
", " + msg;
}
} // namespace } // namespace
LineConsumer::LineConsumer() {}
LineConsumer::~LineConsumer() {}
bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer, bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer,
std::string* out_error) { std::string* out_error) {
int fd; int fd;
@ -175,8 +168,8 @@ bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer,
fd = posix::open(path.c_str(), O_RDONLY); fd = posix::open(path.c_str(), O_RDONLY);
} while (fd < 0 && errno == EINTR); } while (fd < 0 && errno == EINTR);
if (fd < 0) { if (fd < 0) {
*out_error = std::string("error: Unable to open \"") + path + "\", " + *out_error =
strerror(errno); absl::StrCat("error: Unable to open \"", path, "\", ", strerror(errno));
return false; return false;
} }
io::FileInputStream file_stream(fd); io::FileInputStream file_stream(fd);
@ -200,13 +193,14 @@ bool ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
if (!parser.ParseChunk( if (!parser.ParseChunk(
absl::string_view(static_cast<const char*>(buf), buf_len), absl::string_view(static_cast<const char*>(buf), buf_len),
&local_error)) { &local_error)) {
*out_error = *out_error = absl::StrCat("error: ", stream_name, " Line ",
FullErrorString(stream_name, parser.last_line(), local_error); parser.last_line(), ", ", local_error);
return false; return false;
} }
} }
if (!parser.Finish(&local_error)) { if (!parser.Finish(&local_error)) {
*out_error = FullErrorString(stream_name, parser.last_line(), local_error); *out_error = absl::StrCat("error: ", stream_name, " Line ",
parser.last_line(), ", ", local_error);
return false; return false;
} }
return true; return true;

@ -50,10 +50,9 @@ namespace objectivec {
// Helper for parsing simple files. // Helper for parsing simple files.
class PROTOC_EXPORT LineConsumer { class PROTOC_EXPORT LineConsumer {
public: public:
LineConsumer(); LineConsumer() = default;
virtual ~LineConsumer(); virtual ~LineConsumer() = default;
virtual bool ConsumeLine(const absl::string_view& line, virtual bool ConsumeLine(absl::string_view line, std::string* out_error) = 0;
std::string* out_error) = 0;
}; };
bool PROTOC_EXPORT ParseSimpleFile(const std::string& path, bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,

@ -30,8 +30,12 @@
#include "google/protobuf/compiler/objectivec/line_consumer.h" #include "google/protobuf/compiler/objectivec/line_consumer.h"
#include <gtest/gtest.h> #include <string>
#include <tuple>
#include <utility>
#include <vector>
#include <gtest/gtest.h>
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
@ -48,8 +52,7 @@ class TestLineCollector : public LineConsumer {
bool skip_msg = false) bool skip_msg = false)
: lines_(inout_lines), reject_(reject_line), skip_msg_(skip_msg) {} : lines_(inout_lines), reject_(reject_line), skip_msg_(skip_msg) {}
bool ConsumeLine(const absl::string_view& line, bool ConsumeLine(absl::string_view line, std::string* out_error) override {
std::string* out_error) override {
if (reject_ && *reject_ == line) { if (reject_ && *reject_ == line) {
if (!skip_msg_) { if (!skip_msg_) {
*out_error = std::string("Rejected '") + *reject_ + "'"; *out_error = std::string("Rejected '") + *reject_ + "'";

@ -31,11 +31,13 @@
#include "google/protobuf/compiler/objectivec/map_field.h" #include "google/protobuf/compiler/objectivec/map_field.h"
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include <vector>
#include "absl/strings/match.h"
#include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/helpers.h"
#include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/io/printer.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -78,7 +80,7 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) {
// Some compilers report reaching end of function even though all cases of // Some compilers report reaching end of function even though all cases of
// the enum are handed in the switch. // the enum are handed in the switch.
GOOGLE_LOG(FATAL) << "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return NULL; return nullptr;
} }
} // namespace } // namespace
@ -99,18 +101,17 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
std::vector<std::string> field_flags; std::vector<std::string> field_flags;
field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor)); field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor));
// Pull over the current text format custom name values that was calculated. // Pull over the current text format custom name values that was calculated.
if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") != if (absl::StrContains(variables_["fieldflags"],
std::string::npos) { "GPBFieldTextFormatNameCustom")) {
field_flags.push_back("GPBFieldTextFormatNameCustom"); field_flags.push_back("GPBFieldTextFormatNameCustom");
} }
// Pull over some info from the value's flags. // Pull over some info from the value's flags.
const std::string& value_field_flags = const std::string& value_field_flags =
value_field_generator_->variable("fieldflags"); value_field_generator_->variable("fieldflags");
if (value_field_flags.find("GPBFieldHasDefaultValue") != std::string::npos) { if (absl::StrContains(value_field_flags, "GPBFieldHasDefaultValue")) {
field_flags.push_back("GPBFieldHasDefaultValue"); field_flags.push_back("GPBFieldHasDefaultValue");
} }
if (value_field_flags.find("GPBFieldHasEnumDescriptor") != if (absl::StrContains(value_field_flags, "GPBFieldHasEnumDescriptor")) {
std::string::npos) {
field_flags.push_back("GPBFieldHasEnumDescriptor"); field_flags.push_back("GPBFieldHasEnumDescriptor");
} }
@ -146,9 +147,7 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
value_field_generator_->variable("dataTypeSpecific_value"); value_field_generator_->variable("dataTypeSpecific_value");
} }
MapFieldGenerator::~MapFieldGenerator() {} void MapFieldGenerator::FinishInitialization() {
void MapFieldGenerator::FinishInitialization(void) {
RepeatedFieldGenerator::FinishInitialization(); RepeatedFieldGenerator::FinishInitialization();
// Use the array_comment support in RepeatedFieldGenerator to output what the // Use the array_comment support in RepeatedFieldGenerator to output what the
// values in the map are. // values in the map are.

@ -32,6 +32,8 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
#include <map> #include <map>
#include <memory>
#include <set>
#include <string> #include <string>
#include "google/protobuf/compiler/objectivec/field.h" #include "google/protobuf/compiler/objectivec/field.h"
@ -45,20 +47,19 @@ class MapFieldGenerator : public RepeatedFieldGenerator {
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
public: public:
virtual void FinishInitialization(void) override; void FinishInitialization() override;
MapFieldGenerator(const MapFieldGenerator&) = delete; MapFieldGenerator(const MapFieldGenerator&) = delete;
MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; MapFieldGenerator& operator=(const MapFieldGenerator&) = delete;
protected: protected:
explicit MapFieldGenerator(const FieldDescriptor* descriptor); explicit MapFieldGenerator(const FieldDescriptor* descriptor);
virtual ~MapFieldGenerator(); ~MapFieldGenerator() override = default;
virtual void DetermineObjectiveCClassDefinitions( void DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) const override; std::set<std::string>* fwd_decls) const override;
virtual void DetermineForwardDeclarations( void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
std::set<std::string>* fwd_decls, bool include_external_types) const override;
bool include_external_types) const override;
private: private:
std::unique_ptr<FieldGenerator> value_field_generator_; std::unique_ptr<FieldGenerator> value_field_generator_;

@ -32,7 +32,12 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <map>
#include <memory>
#include <set>
#include <sstream> #include <sstream>
#include <string>
#include <vector>
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
@ -206,8 +211,6 @@ MessageGenerator::MessageGenerator(const std::string& root_classname,
} }
} }
MessageGenerator::~MessageGenerator() {}
void MessageGenerator::GenerateStaticVariablesInitialization( void MessageGenerator::GenerateStaticVariablesInitialization(
io::Printer* printer) { io::Printer* printer) {
for (const auto& generator : extension_generators_) { for (const auto& generator : extension_generators_) {
@ -253,7 +256,7 @@ void MessageGenerator::DetermineObjectiveCClassDefinitions(
} }
const Descriptor* containing_descriptor = descriptor_->containing_type(); const Descriptor* containing_descriptor = descriptor_->containing_type();
if (containing_descriptor != NULL) { if (containing_descriptor != nullptr) {
std::string containing_class = ClassName(containing_descriptor); std::string containing_class = ClassName(containing_descriptor);
fwd_decls->insert(ObjCClassDeclaration(containing_class)); fwd_decls->insert(ObjCClassDeclaration(containing_class));
} }
@ -598,7 +601,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
" count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n"); " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
// clang-format on // clang-format on
} }
if (descriptor_->containing_type() != NULL) { if (descriptor_->containing_type() != nullptr) {
std::string containing_class = ClassName(descriptor_->containing_type()); std::string containing_class = ClassName(descriptor_->containing_type());
std::string parent_class_ref = ObjCClass(containing_class); std::string parent_class_ref = ObjCClass(containing_class);
printer->Print( printer->Print(

@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
#include <memory>
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
@ -52,7 +53,7 @@ class MessageGenerator {
public: public:
MessageGenerator(const std::string& root_classname, MessageGenerator(const std::string& root_classname,
const Descriptor* descriptor); const Descriptor* descriptor);
~MessageGenerator(); ~MessageGenerator() = default;
MessageGenerator(const MessageGenerator&) = delete; MessageGenerator(const MessageGenerator&) = delete;
MessageGenerator& operator=(const MessageGenerator&) = delete; MessageGenerator& operator=(const MessageGenerator&) = delete;

@ -31,11 +31,11 @@
#include "google/protobuf/compiler/objectivec/message_field.h" #include "google/protobuf/compiler/objectivec/message_field.h"
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/helpers.h"
#include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/io/printer.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -64,8 +64,6 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor)
SetMessageVariables(descriptor, &variables_); SetMessageVariables(descriptor, &variables_);
} }
MessageFieldGenerator::~MessageFieldGenerator() {}
void MessageFieldGenerator::DetermineForwardDeclarations( void MessageFieldGenerator::DetermineForwardDeclarations(
std::set<std::string>* fwd_decls, bool include_external_types) const { std::set<std::string>* fwd_decls, bool include_external_types) const {
ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls, ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls,
@ -95,8 +93,6 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
"NSMutableArray<" + variables_["storage_type"] + "*>"; "NSMutableArray<" + variables_["storage_type"] + "*>";
} }
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
std::set<std::string>* fwd_decls, bool include_external_types) const { std::set<std::string>* fwd_decls, bool include_external_types) const {
RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls, RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls,

@ -32,6 +32,7 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include "google/protobuf/compiler/objectivec/field.h" #include "google/protobuf/compiler/objectivec/field.h"
@ -46,17 +47,15 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator {
protected: protected:
explicit MessageFieldGenerator(const FieldDescriptor* descriptor); explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
~MessageFieldGenerator() override = default;
MessageFieldGenerator(const MessageFieldGenerator&) = delete; MessageFieldGenerator(const MessageFieldGenerator&) = delete;
MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete;
virtual ~MessageFieldGenerator();
public: public:
virtual void DetermineForwardDeclarations( void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
std::set<std::string>* fwd_decls, bool include_external_types) const override;
bool include_external_types) const override; void DetermineObjectiveCClassDefinitions(
virtual void DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) const override; std::set<std::string>* fwd_decls) const override;
}; };
@ -65,17 +64,16 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
protected: protected:
explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
virtual ~RepeatedMessageFieldGenerator(); ~RepeatedMessageFieldGenerator() override = default;
RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete;
RepeatedMessageFieldGenerator operator=( RepeatedMessageFieldGenerator operator=(
const RepeatedMessageFieldGenerator&) = delete; const RepeatedMessageFieldGenerator&) = delete;
public: public:
virtual void DetermineForwardDeclarations( void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
std::set<std::string>* fwd_decls, bool include_external_types) const override;
bool include_external_types) const override; void DetermineObjectiveCClassDefinitions(
virtual void DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) const override; std::set<std::string>* fwd_decls) const override;
}; };

@ -30,20 +30,24 @@
#include "google/protobuf/compiler/objectivec/names.h" #include "google/protobuf/compiler/objectivec/names.h"
#include <algorithm>
#include <climits> #include <climits>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <map>
#include <ostream>
#include <sstream> #include <sstream>
#include <unordered_set> #include <string>
#include <vector> #include <vector>
#include "google/protobuf/compiler/code_generator.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/objectivec/line_consumer.h" #include "google/protobuf/compiler/objectivec/line_consumer.h"
#include "google/protobuf/compiler/objectivec/nsobject_methods.h" #include "google/protobuf/compiler/objectivec/nsobject_methods.h"
#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// error cases, so it seems to be ok to use as a back door for errors. // error cases, so it seems to be ok to use as a back door for errors.
@ -65,17 +69,16 @@ bool BoolFromEnvVar(const char* env_var, bool default_value) {
class SimpleLineCollector : public LineConsumer { class SimpleLineCollector : public LineConsumer {
public: public:
explicit SimpleLineCollector(std::unordered_set<std::string>* inout_set) explicit SimpleLineCollector(absl::flat_hash_set<std::string>* inout_set)
: set_(inout_set) {} : set_(inout_set) {}
virtual bool ConsumeLine(const absl::string_view& line, bool ConsumeLine(absl::string_view line, std::string* out_error) override {
std::string* out_error) override {
set_->insert(std::string(line)); set_->insert(std::string(line));
return true; return true;
} }
private: private:
std::unordered_set<std::string>* set_; absl::flat_hash_set<std::string>* set_;
}; };
class PackageToPrefixesCollector : public LineConsumer { class PackageToPrefixesCollector : public LineConsumer {
@ -85,8 +88,7 @@ class PackageToPrefixesCollector : public LineConsumer {
std::map<std::string, std::string>* inout_package_to_prefix_map) std::map<std::string, std::string>* inout_package_to_prefix_map)
: usage_(usage), prefix_map_(inout_package_to_prefix_map) {} : usage_(usage), prefix_map_(inout_package_to_prefix_map) {}
virtual bool ConsumeLine(const absl::string_view& line, bool ConsumeLine(absl::string_view line, std::string* out_error) override;
std::string* out_error) override;
private: private:
const std::string usage_; const std::string usage_;
@ -131,7 +133,7 @@ class PrefixModeStorage {
std::string package_to_prefix_mappings_path_; std::string package_to_prefix_mappings_path_;
std::string exception_path_; std::string exception_path_;
std::string forced_prefix_; std::string forced_prefix_;
std::unordered_set<std::string> exceptions_; absl::flat_hash_set<std::string> exceptions_;
}; };
PrefixModeStorage::PrefixModeStorage() { PrefixModeStorage::PrefixModeStorage() {
@ -181,7 +183,7 @@ std::string PrefixModeStorage::prefix_from_proto_package_mappings(
const std::string package = file->package(); const std::string package = file->package();
// For files without packages, the can be registered as "no_package:PATH", // For files without packages, the can be registered as "no_package:PATH",
// allowing the expected prefixes file. // allowing the expected prefixes file.
static const std::string no_package_prefix("no_package:"); const std::string no_package_prefix("no_package:");
const std::string lookup_key = const std::string lookup_key =
package.empty() ? no_package_prefix + file->name() : package; package.empty() ? no_package_prefix + file->name() : package;
@ -220,7 +222,7 @@ bool PrefixModeStorage::is_package_exempted(const std::string& package) {
return exceptions_.count(package) != 0; return exceptions_.count(package) != 0;
} }
PrefixModeStorage g_prefix_mode; PrefixModeStorage& g_prefix_mode = *new PrefixModeStorage();
} // namespace } // namespace
@ -258,19 +260,19 @@ void SetForcedPackagePrefix(const std::string& prefix) {
namespace { namespace {
std::unordered_set<std::string> MakeWordsMap(const char* const words[],
size_t num_words) {
std::unordered_set<std::string> result;
for (int i = 0; i < num_words; i++) {
result.insert(words[i]);
}
return result;
}
const char* const kUpperSegmentsList[] = {"url", "http", "https"}; const char* const kUpperSegmentsList[] = {"url", "http", "https"};
std::unordered_set<std::string> kUpperSegments = const absl::flat_hash_set<absl::string_view>& UpperSegments() {
MakeWordsMap(kUpperSegmentsList, ABSL_ARRAYSIZE(kUpperSegmentsList)); static const auto* words = [] {
auto* words = new absl::flat_hash_set<absl::string_view>();
for (const auto word : kUpperSegmentsList) {
words->emplace(word);
}
return words;
}();
return *words;
}
// Internal helper for name handing. // Internal helper for name handing.
// Do not expose this outside of helpers, stick to having functions for specific // Do not expose this outside of helpers, stick to having functions for specific
@ -318,19 +320,15 @@ std::string UnderscoresToCamelCase(const std::string& input,
std::string result; std::string result;
bool first_segment_forces_upper = false; bool first_segment_forces_upper = false;
for (std::vector<std::string>::iterator i = values.begin(); i != values.end(); for (auto& value : values) {
++i) { bool all_upper = (UpperSegments().count(value) > 0);
std::string value = *i;
bool all_upper = (kUpperSegments.count(value) > 0);
if (all_upper && (result.length() == 0)) { if (all_upper && (result.length() == 0)) {
first_segment_forces_upper = true; first_segment_forces_upper = true;
} }
for (int j = 0; j < value.length(); j++) { if (all_upper) {
if (j == 0 || all_upper) { absl::AsciiStrToUpper(&value);
value[j] = absl::ascii_toupper(value[j]); } else {
} else { value[0] = absl::ascii_toupper(value[0]);
// Nothing, already in lower.
}
} }
result += value; result += value;
} }
@ -525,6 +523,30 @@ const char* const kReservedWordList[] = {
"TimeRecord", "TimeRecord",
}; };
const absl::flat_hash_set<absl::string_view>& ReservedWords() {
static const auto* words = [] {
auto* words = new absl::flat_hash_set<absl::string_view>();
for (const auto word : kReservedWordList) {
words->emplace(word);
}
return words;
}();
return *words;
}
const absl::flat_hash_set<absl::string_view>& NSObjectMethods() {
static const auto* words = [] {
auto* words = new absl::flat_hash_set<absl::string_view>();
for (const auto word : kNSObjectMethodsList) {
words->emplace(word);
}
return words;
}();
return *words;
}
// returns true is input starts with __ or _[A-Z] which are reserved identifiers // returns true is input starts with __ or _[A-Z] which are reserved identifiers
// in C/ C++. All calls should go through UnderscoresToCamelCase before getting // in C/ C++. All calls should go through UnderscoresToCamelCase before getting
// here but this verifies and allows for future expansion if we decide to // here but this verifies and allows for future expansion if we decide to
@ -545,10 +567,6 @@ std::string SanitizeNameForObjC(const std::string& prefix,
const std::string& input, const std::string& input,
const std::string& extension, const std::string& extension,
std::string* out_suffix_added) { std::string* out_suffix_added) {
static const std::unordered_set<std::string> kReservedWords =
MakeWordsMap(kReservedWordList, ABSL_ARRAYSIZE(kReservedWordList));
static const std::unordered_set<std::string> kNSObjectMethods =
MakeWordsMap(kNSObjectMethodsList, ABSL_ARRAYSIZE(kNSObjectMethodsList));
std::string sanitized; std::string sanitized;
// We add the prefix in the cases where the string is missing a prefix. // We add the prefix in the cases where the string is missing a prefix.
// We define "missing a prefix" as where 'input': // We define "missing a prefix" as where 'input':
@ -566,8 +584,8 @@ std::string SanitizeNameForObjC(const std::string& prefix,
sanitized = prefix + input; sanitized = prefix + input;
} }
if (IsReservedCIdentifier(sanitized) || if (IsReservedCIdentifier(sanitized) ||
(kReservedWords.count(sanitized) > 0) || (ReservedWords().count(sanitized) > 0) ||
(kNSObjectMethods.count(sanitized) > 0)) { (NSObjectMethods().count(sanitized) > 0)) {
if (out_suffix_added) *out_suffix_added = extension; if (out_suffix_added) *out_suffix_added = extension;
return sanitized + extension; return sanitized + extension;
} }
@ -604,14 +622,13 @@ void PathSplit(const std::string& path, std::string* directory,
} }
bool IsSpecialNamePrefix(const std::string& name, bool IsSpecialNamePrefix(const std::string& name,
const std::string* special_names, size_t count) { const std::vector<std::string>& special_names) {
for (size_t i = 0; i < count; ++i) { for (const auto& special_name : special_names) {
const size_t length = special_names[i].length(); const size_t length = special_name.length();
if (name.compare(0, length, special_names[i]) == 0) { if (name.compare(0, length, special_name) == 0) {
if (name.length() > length) { if (name.length() > length) {
// If name is longer than the special_names[i] that it matches // If name is longer than the special_name that it matches the next
// the next character must be not lower case (newton vs newTon vs // character must be not lower case (newton vs newTon vs new_ton).
// new_ton).
return !absl::ascii_islower(name[length]); return !absl::ascii_islower(name[length]);
} else { } else {
return true; return true;
@ -635,27 +652,26 @@ void MaybeUnQuote(absl::string_view* input) {
bool IsRetainedName(const std::string& name) { bool IsRetainedName(const std::string& name) {
// List of prefixes from // List of prefixes from
// http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
static const std::string retained_names[] = {"new", "alloc", "copy", static const std::vector<std::string>* retained_names =
"mutableCopy"}; new std::vector<std::string>({"new", "alloc", "copy", "mutableCopy"});
return IsSpecialNamePrefix( return IsSpecialNamePrefix(name, *retained_names);
name, retained_names, sizeof(retained_names) / sizeof(retained_names[0]));
} }
bool IsInitName(const std::string& name) { bool IsInitName(const std::string& name) {
static const std::string init_names[] = {"init"}; static const std::vector<std::string>* init_names =
return IsSpecialNamePrefix(name, init_names, new std::vector<std::string>({"init"});
sizeof(init_names) / sizeof(init_names[0])); return IsSpecialNamePrefix(name, *init_names);
} }
bool IsCreateName(const std::string& name) { bool IsCreateName(const std::string& name) {
// List of segments from // List of segments from
// https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029 // https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029
static const std::string create_names[] = {"Create", "Copy"}; static const std::vector<std::string>* create_names =
const size_t count = sizeof(create_names) / sizeof(create_names[0]); new std::vector<std::string>({"Create", "Copy"});
for (size_t i = 0; i < count; ++i) { for (const auto& create_name : *create_names) {
const size_t length = create_names[i].length(); const size_t length = create_name.length();
size_t pos = name.find(create_names[i]); size_t pos = name.find(create_name);
if (pos != std::string::npos) { if (pos != std::string::npos) {
// The above docs don't actually call out anything about the characters // The above docs don't actually call out anything about the characters
// before the special words. So it's not clear if something like // before the special words. So it's not clear if something like
@ -681,7 +697,7 @@ bool IsCreateName(const std::string& name) {
std::string BaseFileName(const FileDescriptor* file) { std::string BaseFileName(const FileDescriptor* file) {
std::string basename; std::string basename;
PathSplit(file->name(), NULL, &basename); PathSplit(file->name(), nullptr, &basename);
return basename; return basename;
} }
@ -714,7 +730,7 @@ std::string FileClassPrefix(const FileDescriptor* file) {
// underscore at the end. // underscore at the end.
std::string result; std::string result;
const std::vector<std::string> segments = const std::vector<std::string> segments =
absl::StrSplit(file->package(), ".", absl::SkipEmpty()); absl::StrSplit(file->package(), '.', absl::SkipEmpty());
for (const auto& segment : segments) { for (const auto& segment : segments) {
const std::string part = UnderscoresToCamelCase(segment, true); const std::string part = UnderscoresToCamelCase(segment, true);
if (part.empty()) { if (part.empty()) {
@ -767,12 +783,12 @@ std::string FileClassName(const FileDescriptor* file) {
UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root";
// There aren't really any reserved words that end in "Root", but playing // There aren't really any reserved words that end in "Root", but playing
// it safe and checking. // it safe and checking.
return SanitizeNameForObjC(prefix, name, "_RootClass", NULL); return SanitizeNameForObjC(prefix, name, "_RootClass", nullptr);
} }
std::string ClassNameWorker(const Descriptor* descriptor) { std::string ClassNameWorker(const Descriptor* descriptor) {
std::string name; std::string name;
if (descriptor->containing_type() != NULL) { if (descriptor->containing_type() != nullptr) {
name = ClassNameWorker(descriptor->containing_type()); name = ClassNameWorker(descriptor->containing_type());
name += "_"; name += "_";
} }
@ -781,7 +797,7 @@ std::string ClassNameWorker(const Descriptor* descriptor) {
std::string ClassNameWorker(const EnumDescriptor* descriptor) { std::string ClassNameWorker(const EnumDescriptor* descriptor) {
std::string name; std::string name;
if (descriptor->containing_type() != NULL) { if (descriptor->containing_type() != nullptr) {
name = ClassNameWorker(descriptor->containing_type()); name = ClassNameWorker(descriptor->containing_type());
name += "_"; name += "_";
} }
@ -789,7 +805,7 @@ std::string ClassNameWorker(const EnumDescriptor* descriptor) {
} }
std::string ClassName(const Descriptor* descriptor) { std::string ClassName(const Descriptor* descriptor) {
return ClassName(descriptor, NULL); return ClassName(descriptor, nullptr);
} }
std::string ClassName(const Descriptor* descriptor, std::string ClassName(const Descriptor* descriptor,
@ -812,7 +828,7 @@ std::string EnumName(const EnumDescriptor* descriptor) {
// yields Fixed_Class, Fixed_Size. // yields Fixed_Class, Fixed_Size.
const std::string prefix = FileClassPrefix(descriptor->file()); const std::string prefix = FileClassPrefix(descriptor->file());
const std::string name = ClassNameWorker(descriptor); const std::string name = ClassNameWorker(descriptor);
return SanitizeNameForObjC(prefix, name, "_Enum", NULL); return SanitizeNameForObjC(prefix, name, "_Enum", nullptr);
} }
std::string EnumValueName(const EnumValueDescriptor* descriptor) { std::string EnumValueName(const EnumValueDescriptor* descriptor) {
@ -828,7 +844,7 @@ std::string EnumValueName(const EnumValueDescriptor* descriptor) {
const std::string name = class_name + "_" + value_str; const std::string name = class_name + "_" + value_str;
// There aren't really any reserved words with an underscore and a leading // There aren't really any reserved words with an underscore and a leading
// capital letter, but playing it safe and checking. // capital letter, but playing it safe and checking.
return SanitizeNameForObjC("", name, "_Value", NULL); return SanitizeNameForObjC("", name, "_Value", nullptr);
} }
std::string EnumValueShortName(const EnumValueDescriptor* descriptor) { std::string EnumValueShortName(const EnumValueDescriptor* descriptor) {
@ -865,7 +881,7 @@ std::string UnCamelCaseEnumShortName(const std::string& name) {
std::string ExtensionMethodName(const FieldDescriptor* descriptor) { std::string ExtensionMethodName(const FieldDescriptor* descriptor) {
const std::string name = NameFromFieldDescriptor(descriptor); const std::string name = NameFromFieldDescriptor(descriptor);
const std::string result = UnderscoresToCamelCase(name, false); const std::string result = UnderscoresToCamelCase(name, false);
return SanitizeNameForObjC("", result, "_Extension", NULL); return SanitizeNameForObjC("", result, "_Extension", nullptr);
} }
std::string FieldName(const FieldDescriptor* field) { std::string FieldName(const FieldDescriptor* field) {
@ -880,7 +896,7 @@ std::string FieldName(const FieldDescriptor* field) {
result += "_p"; result += "_p";
} }
} }
return SanitizeNameForObjC("", result, "_p", NULL); return SanitizeNameForObjC("", result, "_p", nullptr);
} }
std::string FieldNameCapitalized(const FieldDescriptor* field) { std::string FieldNameCapitalized(const FieldDescriptor* field) {
@ -960,10 +976,8 @@ const char* const ProtobufLibraryFrameworkName = "Protobuf";
std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) { std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) {
// GPB_USE_[framework_name]_FRAMEWORK_IMPORTS // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS
std::string result = std::string("GPB_USE_"); return absl::StrCat("GPB_USE_", absl::AsciiStrToUpper(framework_name),
result += absl::AsciiStrToUpper(framework_name); "_FRAMEWORK_IMPORTS");
result += "_FRAMEWORK_IMPORTS";
return result;
} }
bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) { bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) {
@ -988,12 +1002,12 @@ bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) {
namespace { namespace {
bool PackageToPrefixesCollector::ConsumeLine(const absl::string_view& line, bool PackageToPrefixesCollector::ConsumeLine(absl::string_view line,
std::string* out_error) { std::string* out_error) {
int offset = line.find('='); int offset = line.find('=');
if (offset == absl::string_view::npos) { if (offset == absl::string_view::npos) {
*out_error = *out_error =
usage_ + " file line without equal sign: '" + absl::StrCat(line) + "'."; absl::StrCat(usage_, " file line without equal sign: '", line, "'.");
return false; return false;
} }
absl::string_view package = absl::string_view package =
@ -1034,7 +1048,7 @@ bool ValidateObjCClassPrefix(
const std::string package = file->package(); const std::string package = file->package();
// For files without packages, the can be registered as "no_package:PATH", // For files without packages, the can be registered as "no_package:PATH",
// allowing the expected prefixes file. // allowing the expected prefixes file.
static const std::string no_package_prefix("no_package:"); const std::string no_package_prefix("no_package:");
const std::string lookup_key = const std::string lookup_key =
package.empty() ? no_package_prefix + file->name() : package; package.empty() ? no_package_prefix + file->name() : package;
@ -1175,7 +1189,7 @@ Options::Options() {
getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS"); getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS");
if (suppressions) { if (suppressions) {
expected_prefixes_suppressions = expected_prefixes_suppressions =
absl::StrSplit(suppressions, ";", absl::SkipEmpty()); absl::StrSplit(suppressions, ';', absl::SkipEmpty());
} }
prefixes_must_be_registered = prefixes_must_be_registered =
BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false); BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false);
@ -1190,36 +1204,36 @@ bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
} }
bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
const Options& generation_options, const Options& validation_options,
std::string* out_error) { std::string* out_error) {
// Allow a '-' as the path for the expected prefixes to completely disable // Allow a '-' as the path for the expected prefixes to completely disable
// even the most basic of checks. // even the most basic of checks.
if (generation_options.expected_prefixes_path == "-") { if (validation_options.expected_prefixes_path == "-") {
return true; return true;
} }
// Load the expected package prefixes, if available, to validate against. // Load the expected package prefixes, if available, to validate against.
std::map<std::string, std::string> expected_package_prefixes; std::map<std::string, std::string> expected_package_prefixes;
if (!LoadExpectedPackagePrefixes(generation_options.expected_prefixes_path, if (!LoadExpectedPackagePrefixes(validation_options.expected_prefixes_path,
&expected_package_prefixes, out_error)) { &expected_package_prefixes, out_error)) {
return false; return false;
} }
for (int i = 0; i < files.size(); i++) { for (auto file : files) {
bool should_skip = bool should_skip =
(std::find(generation_options.expected_prefixes_suppressions.begin(), (std::find(validation_options.expected_prefixes_suppressions.begin(),
generation_options.expected_prefixes_suppressions.end(), validation_options.expected_prefixes_suppressions.end(),
files[i]->name()) != file->name()) !=
generation_options.expected_prefixes_suppressions.end()); validation_options.expected_prefixes_suppressions.end());
if (should_skip) { if (should_skip) {
continue; continue;
} }
bool is_valid = ValidateObjCClassPrefix( bool is_valid =
files[i], generation_options.expected_prefixes_path, ValidateObjCClassPrefix(file, validation_options.expected_prefixes_path,
expected_package_prefixes, expected_package_prefixes,
generation_options.prefixes_must_be_registered, validation_options.prefixes_must_be_registered,
generation_options.require_prefixes, out_error); validation_options.require_prefixes, out_error);
if (!is_valid) { if (!is_valid) {
return false; return false;
} }

@ -37,7 +37,6 @@
#include <vector> #include <vector>
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/io/zero_copy_stream.h"
// Must be included last // Must be included last
#include "google/protobuf/port_def.inc" #include "google/protobuf/port_def.inc"
@ -48,88 +47,88 @@ namespace compiler {
namespace objectivec { namespace objectivec {
// Get/Set the path to a file to load for objc class prefix lookups. // Get/Set the path to a file to load for objc class prefix lookups.
std::string PROTOC_EXPORT GetPackageToPrefixMappingsPath(); PROTOC_EXPORT std::string GetPackageToPrefixMappingsPath();
void PROTOC_EXPORT SetPackageToPrefixMappingsPath(const std::string& file_path); PROTOC_EXPORT void SetPackageToPrefixMappingsPath(const std::string& file_path);
// Get/Set if the proto package should be used to make the default prefix for // Get/Set if the proto package should be used to make the default prefix for
// symbols. This will then impact most of the type naming apis below. It is done // symbols. This will then impact most of the type naming apis below. It is done
// as a global to not break any other generator reusing the methods since they // as a global to not break any other generator reusing the methods since they
// are exported. // are exported.
bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix(); PROTOC_EXPORT bool UseProtoPackageAsDefaultPrefix();
void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off); PROTOC_EXPORT void SetUseProtoPackageAsDefaultPrefix(bool on_or_off);
// Get/Set the path to a file to load as exceptions when // Get/Set the path to a file to load as exceptions when
// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there // `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there
// should be no exceptions. // should be no exceptions.
std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList(); PROTOC_EXPORT std::string GetProtoPackagePrefixExceptionList();
void PROTOC_EXPORT PROTOC_EXPORT void SetProtoPackagePrefixExceptionList(
SetProtoPackagePrefixExceptionList(const std::string& file_path); const std::string& file_path);
// Get/Set a prefix to add before the prefix generated from the package name. // Get/Set a prefix to add before the prefix generated from the package name.
// This is only used when UseProtoPackageAsDefaultPrefix() is True. // This is only used when UseProtoPackageAsDefaultPrefix() is True.
std::string PROTOC_EXPORT GetForcedPackagePrefix(); PROTOC_EXPORT std::string GetForcedPackagePrefix();
void PROTOC_EXPORT SetForcedPackagePrefix(const std::string& prefix); PROTOC_EXPORT void SetForcedPackagePrefix(const std::string& prefix);
// Returns true if the name requires a ns_returns_not_retained attribute applied // Returns true if the name requires a ns_returns_not_retained attribute applied
// to it. // to it.
bool PROTOC_EXPORT IsRetainedName(const std::string& name); PROTOC_EXPORT bool IsRetainedName(const std::string& name);
// Returns true if the name starts with "init" and will need to have special // Returns true if the name starts with "init" and will need to have special
// handling under ARC. // handling under ARC.
bool PROTOC_EXPORT IsInitName(const std::string& name); PROTOC_EXPORT bool IsInitName(const std::string& name);
// Returns true if the name requires a cf_returns_not_retained attribute applied // Returns true if the name requires a cf_returns_not_retained attribute applied
// to it. // to it.
bool PROTOC_EXPORT IsCreateName(const std::string& name); PROTOC_EXPORT bool IsCreateName(const std::string& name);
// Gets the objc_class_prefix or the prefix made from the proto package. // Gets the objc_class_prefix or the prefix made from the proto package.
std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file); PROTOC_EXPORT std::string FileClassPrefix(const FileDescriptor* file);
// Gets the path of the file we're going to generate (sans the .pb.h // Gets the path of the file we're going to generate (sans the .pb.h
// extension). The path will be dependent on the objectivec package // extension). The path will be dependent on the objectivec package
// declared in the proto package. // declared in the proto package.
std::string PROTOC_EXPORT FilePath(const FileDescriptor* file); PROTOC_EXPORT std::string FilePath(const FileDescriptor* file);
// Just like FilePath(), but without the directory part. // Just like FilePath(), but without the directory part.
std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file); PROTOC_EXPORT std::string FilePathBasename(const FileDescriptor* file);
// Gets the name of the root class we'll generate in the file. This class // Gets the name of the root class we'll generate in the file. This class
// is not meant for external consumption, but instead contains helpers that // is not meant for external consumption, but instead contains helpers that
// the rest of the classes need // the rest of the classes need
std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file); PROTOC_EXPORT std::string FileClassName(const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given // These return the fully-qualified class name corresponding to the given
// descriptor. // descriptor.
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor); PROTOC_EXPORT std::string ClassName(const Descriptor* descriptor);
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor, PROTOC_EXPORT std::string ClassName(const Descriptor* descriptor,
std::string* out_suffix_added); std::string* out_suffix_added);
std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor); PROTOC_EXPORT std::string EnumName(const EnumDescriptor* descriptor);
// Returns the fully-qualified name of the enum value corresponding to the // Returns the fully-qualified name of the enum value corresponding to the
// the descriptor. // the descriptor.
std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor); PROTOC_EXPORT std::string EnumValueName(const EnumValueDescriptor* descriptor);
// Returns the name of the enum value corresponding to the descriptor. // Returns the name of the enum value corresponding to the descriptor.
std::string PROTOC_EXPORT PROTOC_EXPORT std::string EnumValueShortName(
EnumValueShortName(const EnumValueDescriptor* descriptor); const EnumValueDescriptor* descriptor);
// Reverse what an enum does. // Reverse what an enum does.
std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name); PROTOC_EXPORT std::string UnCamelCaseEnumShortName(const std::string& name);
// Returns the name to use for the extension (used as the method off the file's // Returns the name to use for the extension (used as the method off the file's
// Root class). // Root class).
std::string PROTOC_EXPORT PROTOC_EXPORT std::string ExtensionMethodName(
ExtensionMethodName(const FieldDescriptor* descriptor); const FieldDescriptor* descriptor);
// Returns the transformed field name. // Returns the transformed field name.
std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field); PROTOC_EXPORT std::string FieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field); PROTOC_EXPORT std::string FieldNameCapitalized(const FieldDescriptor* field);
// Returns the transformed oneof name. // Returns the transformed oneof name.
std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor); PROTOC_EXPORT std::string OneofEnumName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor); PROTOC_EXPORT std::string OneofName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT PROTOC_EXPORT std::string OneofNameCapitalized(
OneofNameCapitalized(const OneofDescriptor* descriptor); const OneofDescriptor* descriptor);
// Reverse of the above. // Reverse of the above.
std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name, PROTOC_EXPORT std::string UnCamelCaseFieldName(const std::string& name,
const FieldDescriptor* field); const FieldDescriptor* field);
// The name the commonly used by the library when built as a framework. // The name the commonly used by the library when built as a framework.
@ -137,8 +136,8 @@ std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name,
extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName; extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName;
// Returns the CPP symbol name to use as the gate for framework style imports // Returns the CPP symbol name to use as the gate for framework style imports
// for the given framework name to use. // for the given framework name to use.
std::string PROTOC_EXPORT PROTOC_EXPORT std::string ProtobufFrameworkImportSymbol(
ProtobufFrameworkImportSymbol(const std::string& framework_name); const std::string& framework_name);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -146,8 +145,8 @@ ProtobufFrameworkImportSymbol(const std::string& framework_name);
// building on top of ObjC Protos to be able to share the knowledge/enforcement. // building on top of ObjC Protos to be able to share the knowledge/enforcement.
// Checks if the file is one of the proto's bundled with the library. // Checks if the file is one of the proto's bundled with the library.
bool PROTOC_EXPORT PROTOC_EXPORT bool IsProtobufLibraryBundledProtoFile(
IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); const FileDescriptor* file);
// Generator Prefix Validation Options (see generator.cc for a // Generator Prefix Validation Options (see generator.cc for a
// description of each): // description of each):
@ -162,12 +161,12 @@ struct Options {
// Checks the prefix for the given files and outputs any warnings as needed. If // Checks the prefix for the given files and outputs any warnings as needed. If
// there are flat out errors, then out_error is filled in with the first error // there are flat out errors, then out_error is filled in with the first error
// and the result is false. // and the result is false.
bool PROTOC_EXPORT ValidateObjCClassPrefixes( PROTOC_EXPORT bool ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files, const std::vector<const FileDescriptor*>& files,
const Options& validation_options, std::string* out_error); const Options& validation_options, std::string* out_error);
// Same was the other ValidateObjCClassPrefixes() calls, but the options all // Same was the other ValidateObjCClassPrefixes() calls, but the options all
// come from the environment variables. // come from the environment variables.
bool PROTOC_EXPORT ValidateObjCClassPrefixes( PROTOC_EXPORT bool ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files, std::string* out_error); const std::vector<const FileDescriptor*>& files, std::string* out_error);
} // namespace objectivec } // namespace objectivec

@ -32,8 +32,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {

@ -62,8 +62,6 @@ OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
variables_["comments"] = comments; variables_["comments"] = comments;
} }
OneofGenerator::~OneofGenerator() {}
void OneofGenerator::SetOneofIndexBase(int index_base) { void OneofGenerator::SetOneofIndexBase(int index_base) {
int index = descriptor_->index() + index_base; int index = descriptor_->index() + index_base;
// Flip the sign to mark it as a oneof. // Flip the sign to mark it as a oneof.
@ -128,11 +126,11 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
// clang-format on // clang-format on
} }
std::string OneofGenerator::DescriptorName(void) const { std::string OneofGenerator::DescriptorName() const {
return variables_.find("name")->second; return variables_.find("name")->second;
} }
std::string OneofGenerator::HasIndexAsString(void) const { std::string OneofGenerator::HasIndexAsString() const {
return variables_.find("index")->second; return variables_.find("index")->second;
} }

@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
#include <map>
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
@ -46,7 +47,7 @@ namespace objectivec {
class OneofGenerator { class OneofGenerator {
public: public:
explicit OneofGenerator(const OneofDescriptor* descriptor); explicit OneofGenerator(const OneofDescriptor* descriptor);
~OneofGenerator(); ~OneofGenerator() = default;
OneofGenerator(const OneofGenerator&) = delete; OneofGenerator(const OneofGenerator&) = delete;
OneofGenerator& operator=(const OneofGenerator&) = delete; OneofGenerator& operator=(const OneofGenerator&) = delete;
@ -61,8 +62,8 @@ class OneofGenerator {
void GeneratePropertyImplementation(io::Printer* printer); void GeneratePropertyImplementation(io::Printer* printer);
void GenerateClearFunctionImplementation(io::Printer* printer); void GenerateClearFunctionImplementation(io::Printer* printer);
std::string DescriptorName(void) const; std::string DescriptorName() const;
std::string HasIndexAsString(void) const; std::string HasIndexAsString() const;
private: private:
const OneofDescriptor* descriptor_; const OneofDescriptor* descriptor_;

@ -35,7 +35,6 @@
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "google/protobuf/compiler/objectivec/helpers.h" #include "google/protobuf/compiler/objectivec/helpers.h"
#include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
namespace google { namespace google {
@ -43,9 +42,6 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace objectivec { namespace objectivec {
using internal::WireFormat;
using internal::WireFormatLite;
namespace { namespace {
const char* PrimitiveTypeName(const FieldDescriptor* descriptor) { const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
@ -72,13 +68,13 @@ const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
case OBJECTIVECTYPE_ENUM: case OBJECTIVECTYPE_ENUM:
return "int32_t"; return "int32_t";
case OBJECTIVECTYPE_MESSAGE: case OBJECTIVECTYPE_MESSAGE:
return NULL; // Messages go through message_field.cc|h. return nullptr; // Messages go through message_field.cc|h.
} }
// Some compilers report reaching end of function even though all cases of // Some compilers report reaching end of function even though all cases of
// the enum are handed in the switch. // the enum are handed in the switch.
GOOGLE_LOG(FATAL) << "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return NULL; return nullptr;
} }
const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) { const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
@ -112,7 +108,7 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
// Some compilers report reaching end of function even though all cases of // Some compilers report reaching end of function even though all cases of
// the enum are handed in the switch. // the enum are handed in the switch.
GOOGLE_LOG(FATAL) << "Can't get here."; GOOGLE_LOG(FATAL) << "Can't get here.";
return NULL; return nullptr;
} }
void SetPrimitiveVariables(const FieldDescriptor* descriptor, void SetPrimitiveVariables(const FieldDescriptor* descriptor,
@ -130,8 +126,6 @@ PrimitiveFieldGenerator::PrimitiveFieldGenerator(
SetPrimitiveVariables(descriptor, &variables_); SetPrimitiveVariables(descriptor, &variables_);
} }
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration( void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
io::Printer* printer) const { io::Printer* printer) const {
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
@ -141,7 +135,7 @@ void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
} }
} }
int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const { int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded() const {
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
// Reserve a bit for the storage of the boolean. // Reserve a bit for the storage of the boolean.
return 1; return 1;
@ -149,10 +143,10 @@ int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
return 0; return 0;
} }
void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
// Set into the offset the has bit to use for the actual value. // Set into the offset the has bit to use for the actual value.
variables_["storage_offset_value"] = absl::StrCat(has_base); variables_["storage_offset_value"] = absl::StrCat(index_base);
variables_["storage_offset_comment"] = variables_["storage_offset_comment"] =
" // Stored in _has_storage_ to save space."; " // Stored in _has_storage_ to save space.";
} }
@ -165,8 +159,6 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
variables_["property_storage_attribute"] = "copy"; variables_["property_storage_attribute"] = "copy";
} }
PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {}
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
const FieldDescriptor* descriptor) const FieldDescriptor* descriptor)
: RepeatedFieldGenerator(descriptor) { : RepeatedFieldGenerator(descriptor) {
@ -182,8 +174,6 @@ RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
} }
} }
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
} // namespace objectivec } // namespace objectivec
} // namespace compiler } // namespace compiler
} // namespace protobuf } // namespace protobuf

@ -43,16 +43,15 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator {
protected: protected:
explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
virtual ~PrimitiveFieldGenerator(); ~PrimitiveFieldGenerator() override = default;
PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete;
PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete; PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete;
virtual void GenerateFieldStorageDeclaration( void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
io::Printer* printer) const override;
virtual int ExtraRuntimeHasBitsNeeded(void) const override; int ExtraRuntimeHasBitsNeeded() const override;
virtual void SetExtraRuntimeHasBitsBase(int index_base) override; void SetExtraRuntimeHasBitsBase(int index_base) override;
}; };
class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
@ -60,7 +59,7 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
protected: protected:
explicit PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor); explicit PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor);
virtual ~PrimitiveObjFieldGenerator(); ~PrimitiveObjFieldGenerator() override = default;
PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete;
PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) = PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) =
@ -72,7 +71,7 @@ class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator {
protected: protected:
explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
virtual ~RepeatedPrimitiveFieldGenerator(); ~RepeatedPrimitiveFieldGenerator() override = default;
RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) =
delete; delete;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save