PROTOBUF_SYNC_PIPER
pull/9912/head
Adam Cozzette 3 years ago
commit f744bddb63
  1. 4
      BUILD.bazel
  2. 71
      Makefile.am
  3. 2
      benchmarks/BUILD.bazel
  4. 2
      benchmarks/datasets/BUILD.bazel
  5. 3
      cmake/extract_includes.bat.in
  6. 3
      cmake/libprotoc.cmake
  7. 2
      java/BUILD.bazel
  8. 8
      java/core/BUILD.bazel
  9. 2
      java/internal/BUILD.bazel
  10. 6
      java/kotlin-lite/BUILD.bazel
  11. 6
      java/kotlin/BUILD.bazel
  12. 1
      java/kotlin/generate-sources-build.xml
  13. 2
      java/lite/BUILD.bazel
  14. 6
      java/util/BUILD.bazel
  15. 11
      kokoro/macos/objectivec_cocoapods_integration/build.sh
  16. 5
      kokoro/macos/objectivec_cocoapods_integration/continuous.cfg
  17. 5
      kokoro/macos/objectivec_cocoapods_integration/presubmit.cfg
  18. 290
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj
  19. 7
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  20. 91
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme
  21. 37
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h
  22. 48
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m
  23. 58
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json
  24. 680
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib
  25. 34
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist
  26. 35
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m
  27. 10
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework
  28. 8
      objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static
  29. 9
      objectivec/Tests/CocoaPods/README.md
  30. 10
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework
  31. 8
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static
  32. 309
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj
  33. 7
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  34. 91
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme
  35. 39
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h
  36. 67
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m
  37. 68
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json
  38. 27
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard
  39. 26
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard
  40. 47
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist
  41. 37
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h
  42. 49
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m
  43. 39
      objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m
  44. 150
      objectivec/Tests/CocoaPods/run_tests.sh
  45. 39
      pkg/BUILD.bazel
  46. 452
      pkg/build_systems.bzl
  47. 2
      python/google/protobuf/pyext/extension_dict.h
  48. 1
      python/google/protobuf/pyext/map_container.h
  49. 4
      python/google/protobuf/pyext/repeated_composite_container.h
  50. 2
      python/google/protobuf/pyext/repeated_scalar_container.h
  51. 3
      src/Makefile.am
  52. 9
      src/google/protobuf/compiler/cpp/enum_field.cc
  53. 4
      src/google/protobuf/compiler/cpp/enum_field.h
  54. 18
      src/google/protobuf/compiler/cpp/field.cc
  55. 5
      src/google/protobuf/compiler/cpp/field.h
  56. 67
      src/google/protobuf/compiler/cpp/file.cc
  57. 114
      src/google/protobuf/compiler/cpp/helpers.cc
  58. 45
      src/google/protobuf/compiler/cpp/helpers.h
  59. 12
      src/google/protobuf/compiler/cpp/map_field.cc
  60. 266
      src/google/protobuf/compiler/cpp/message.cc
  61. 3
      src/google/protobuf/compiler/cpp/message.h
  62. 19
      src/google/protobuf/compiler/cpp/message_field.cc
  63. 20
      src/google/protobuf/compiler/cpp/parse_function_generator.cc
  64. 8
      src/google/protobuf/compiler/cpp/primitive_field.cc
  65. 4
      src/google/protobuf/compiler/cpp/primitive_field.h
  66. 40
      src/google/protobuf/compiler/cpp/string_field.cc
  67. 5
      src/google/protobuf/compiler/cpp/string_field.h
  68. 2
      src/google/protobuf/compiler/csharp/csharp_enum_field.h
  69. 2
      src/google/protobuf/compiler/csharp/csharp_map_field.h
  70. 2
      src/google/protobuf/compiler/csharp/csharp_message_field.h
  71. 2
      src/google/protobuf/compiler/csharp/csharp_primitive_field.h
  72. 2
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
  73. 2
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
  74. 2
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
  75. 2
      src/google/protobuf/compiler/csharp/csharp_wrapper_field.h
  76. 136
      src/google/protobuf/compiler/objectivec/objectivec_file.cc
  77. 27
      src/google/protobuf/compiler/objectivec/objectivec_file.h
  78. 3
      src/google/protobuf/compiler/objectivec/objectivec_generator.cc
  79. 2
      src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
  80. 129
      src/google/protobuf/unittest.proto
  81. 5
      tests.sh

@ -1496,7 +1496,7 @@ pkg_files(
"protobuf*.pc.in", "protobuf*.pc.in",
"test-driver", "test-driver",
], allow_empty = True) + [ ], allow_empty = True) + [
"BUILD", "BUILD.bazel",
"CHANGES.txt", "CHANGES.txt",
"CMakeLists.txt", "CMakeLists.txt",
"CONTRIBUTORS.txt", "CONTRIBUTORS.txt",
@ -1512,7 +1512,7 @@ pkg_files(
"maven_install.json", "maven_install.json",
"update_file_lists.sh", "update_file_lists.sh",
"//third_party:zlib.BUILD", "//third_party:zlib.BUILD",
"//util/python:BUILD", "//util/python:BUILD.bazel",
], ],
strip_prefix = strip_prefix.from_root(""), strip_prefix = strip_prefix.from_root(""),
visibility = ["//pkg:__pkg__"], visibility = ["//pkg:__pkg__"],

@ -11,7 +11,7 @@ SUBDIRS = . src
# Always include third_party directories in distributions. # Always include third_party directories in distributions.
# #
# Note that distribution artifacts will be produced by Bazel in the future. # Note that distribution artifacts will be produced by Bazel in the future.
# See pkg/BUILD for overall definitions. # See pkg/BUILD.bazel for overall definitions.
DIST_SUBDIRS = src conformance benchmarks third_party/googletest DIST_SUBDIRS = src conformance benchmarks third_party/googletest
# Build gmock before we build protobuf tests. We don't add gmock to SUBDIRS # Build gmock before we build protobuf tests. We don't add gmock to SUBDIRS
@ -51,7 +51,7 @@ clean-local:
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = protobuf.pc protobuf-lite.pc pkgconfig_DATA = protobuf.pc protobuf-lite.pc
# Note: please keep this in sync with the dist_files rule in csharp/BUILD. # Note: please keep this in sync with the dist_files rule in csharp/BUILD.bazel.
csharp_EXTRA_DIST= \ csharp_EXTRA_DIST= \
global.json \ global.json \
csharp/.editorconfig \ csharp/.editorconfig \
@ -283,11 +283,11 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/UnknownFieldSet.cs \ csharp/src/Google.Protobuf/UnknownFieldSet.cs \
csharp/src/Google.Protobuf/UnsafeByteOperations.cs csharp/src/Google.Protobuf/UnsafeByteOperations.cs
# Note: please keep this in sync with the dist_files rules under java/.../BUILD. # Note: please keep this in sync with the dist_files rules under java/.../BUILD.bazel.
java_EXTRA_DIST= \ java_EXTRA_DIST= \
java/README.md \ java/README.md \
java/bom/pom.xml \ java/bom/pom.xml \
java/core/BUILD \ java/core/BUILD.bazel \
java/core/generate-sources-build.xml \ java/core/generate-sources-build.xml \
java/core/generate-test-sources-build.xml \ java/core/generate-test-sources-build.xml \
java/core/pom.xml \ java/core/pom.xml \
@ -543,9 +543,9 @@ java_EXTRA_DIST=
java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \ java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \
java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \ java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \
java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \ java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \
java/internal/BUILD \ java/internal/BUILD.bazel \
java/internal/testing.bzl \ java/internal/testing.bzl \
java/kotlin/BUILD \ java/kotlin/BUILD.bazel \
java/kotlin/generate-sources-build.xml \ java/kotlin/generate-sources-build.xml \
java/kotlin/generate-test-sources-build.xml \ java/kotlin/generate-test-sources-build.xml \
java/kotlin/pom.xml \ java/kotlin/pom.xml \
@ -572,7 +572,7 @@ java_EXTRA_DIST=
java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto3.proto \ java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto3.proto \
java/kotlin/src/test/proto/com/google/protobuf/example_extensible_message.proto \ java/kotlin/src/test/proto/com/google/protobuf/example_extensible_message.proto \
java/kotlin/src/test/proto/com/google/protobuf/multiple_files_proto3.proto \ java/kotlin/src/test/proto/com/google/protobuf/multiple_files_proto3.proto \
java/kotlin-lite/BUILD \ java/kotlin-lite/BUILD.bazel \
java/kotlin-lite/generate-sources-build.xml \ java/kotlin-lite/generate-sources-build.xml \
java/kotlin-lite/generate-test-sources-build.xml \ java/kotlin-lite/generate-test-sources-build.xml \
java/kotlin-lite/lite.awk \ java/kotlin-lite/lite.awk \
@ -583,7 +583,7 @@ java_EXTRA_DIST=
java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt\ java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt\
java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt \ java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt \
java/lite.md \ java/lite.md \
java/lite/BUILD \ java/lite/BUILD.bazel \
java/lite/generate-sources-build.xml \ java/lite/generate-sources-build.xml \
java/lite/generate-test-sources-build.xml \ java/lite/generate-test-sources-build.xml \
java/lite/lite.awk \ java/lite/lite.awk \
@ -591,9 +591,9 @@ java_EXTRA_DIST=
java/lite/pom_template.xml \ java/lite/pom_template.xml \
java/lite/process-lite-sources-build.xml \ java/lite/process-lite-sources-build.xml \
java/lite/src/test/java/com/google/protobuf/LiteTest.java \ java/lite/src/test/java/com/google/protobuf/LiteTest.java \
java/BUILD \ java/BUILD.bazel \
java/pom.xml \ java/pom.xml \
java/util/BUILD \ java/util/BUILD.bazel \
java/util/pom.xml \ java/util/pom.xml \
java/util/pom_template.xml \ java/util/pom_template.xml \
java/util/src/main/java/com/google/protobuf/util/Durations.java \ java/util/src/main/java/com/google/protobuf/util/Durations.java \
@ -612,10 +612,10 @@ java_EXTRA_DIST=
java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \ java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \
java/util/src/test/proto/com/google/protobuf/util/json_test.proto java/util/src/test/proto/com/google/protobuf/util/json_test.proto
# Note: please keep this in sync with the dist_files rule in objectivec/BUILD. # Note: please keep this in sync with the dist_files rule in objectivec/BUILD.bazel.
objectivec_EXTRA_DIST= \ objectivec_EXTRA_DIST= \
objectivec/.clang-format \ objectivec/.clang-format \
objectivec/BUILD \ objectivec/BUILD.bazel \
objectivec/DevTools/check_version_stamps.sh \ objectivec/DevTools/check_version_stamps.sh \
objectivec/DevTools/compile_testing_protos.sh \ objectivec/DevTools/compile_testing_protos.sh \
objectivec/DevTools/full_mac_build.sh \ objectivec/DevTools/full_mac_build.sh \
@ -714,33 +714,6 @@ objectivec_EXTRA_DIST= \
objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \ objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \
objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \ objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \
objectivec/README.md \ objectivec/README.md \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework \
objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static \
objectivec/Tests/CocoaPods/README.md \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m \
objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m \
objectivec/Tests/CocoaPods/run_tests.sh \
objectivec/Tests/golden_message \ objectivec/Tests/golden_message \
objectivec/Tests/golden_packed_fields_message \ objectivec/Tests/golden_packed_fields_message \
objectivec/Tests/GPBARCUnittestProtos.m \ objectivec/Tests/GPBARCUnittestProtos.m \
@ -821,7 +794,7 @@ objectivec_EXTRA_DIST= \
objectivec/Tests/UnitTests-Info.plist \ objectivec/Tests/UnitTests-Info.plist \
Protobuf.podspec Protobuf.podspec
# Note: please keep this in sync with the dist_files rule in php/BUILD. # Note: please keep this in sync with the dist_files rule in php/BUILD.bazel.
php_EXTRA_DIST= \ php_EXTRA_DIST= \
php/README.md \ php/README.md \
php/REFCOUNTING.md \ php/REFCOUNTING.md \
@ -1018,7 +991,7 @@ php_EXTRA_DIST= \
php/tests/WellKnownTest.php \ php/tests/WellKnownTest.php \
php/tests/WrapperTypeSettersTest.php php/tests/WrapperTypeSettersTest.php
# Note: please keep this in sync with the python_dist_files rule in BUILD. # Note: please keep this in sync with the python_dist_files rule in BUILD.bazel.
python_EXTRA_DIST= \ python_EXTRA_DIST= \
python/MANIFEST.in \ python/MANIFEST.in \
python/google/__init__.py \ python/google/__init__.py \
@ -1142,7 +1115,7 @@ python_EXTRA_DIST= \
python/tox.ini \ python/tox.ini \
python/README.md python/README.md
# Note: please keep this in sync with the dist_files rule in ruby/BUILD. # Note: please keep this in sync with the dist_files rule in ruby/BUILD.bazel.
ruby_EXTRA_DIST= \ ruby_EXTRA_DIST= \
ruby/Gemfile \ ruby/Gemfile \
ruby/.gitignore \ ruby/.gitignore \
@ -1220,7 +1193,7 @@ ruby_EXTRA_DIST= \
all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST)
# Note: please keep this in sync with the common_dist_files rule in BUILD. # Note: please keep this in sync with the common_dist_files rule in BUILD.bazel.
EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
autogen.sh \ autogen.sh \
generate_descriptor_proto.sh \ generate_descriptor_proto.sh \
@ -1229,7 +1202,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
CONTRIBUTORS.txt \ CONTRIBUTORS.txt \
CHANGES.txt \ CHANGES.txt \
update_file_lists.sh \ update_file_lists.sh \
BUILD \ BUILD.bazel \
WORKSPACE \ WORKSPACE \
CMakeLists.txt \ CMakeLists.txt \
cmake/abseil-cpp.cmake \ cmake/abseil-cpp.cmake \
@ -1254,12 +1227,12 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
compiler_config_setting.bzl \ compiler_config_setting.bzl \
build_files_updated_unittest.sh \ build_files_updated_unittest.sh \
cc_proto_blacklist_test.bzl \ cc_proto_blacklist_test.bzl \
csharp/BUILD \ csharp/BUILD.bazel \
editors/README.txt \ editors/README.txt \
editors/proto.vim \ editors/proto.vim \
editors/protobuf-mode.el \ editors/protobuf-mode.el \
examples/AddPerson.java \ examples/AddPerson.java \
examples/BUILD \ examples/BUILD.bazel \
examples/CMakeLists.txt \ examples/CMakeLists.txt \
examples/ListPeople.java \ examples/ListPeople.java \
examples/Makefile \ examples/Makefile \
@ -1281,14 +1254,14 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
examples/pubspec.yaml \ examples/pubspec.yaml \
internal.bzl \ internal.bzl \
maven_install.json \ maven_install.json \
php/BUILD \ php/BUILD.bazel \
protobuf.bzl \ protobuf.bzl \
protobuf_deps.bzl \ protobuf_deps.bzl \
protobuf_release.bzl \ protobuf_release.bzl \
protobuf_version.bzl \ protobuf_version.bzl \
ruby/BUILD \ ruby/BUILD.bazel \
third_party/zlib.BUILD \ third_party/zlib.BUILD \
util/python/BUILD util/python/BUILD.bazel
# Deletes all the files generated by autogen.sh. # Deletes all the files generated by autogen.sh.
MAINTAINERCLEANFILES = \ MAINTAINERCLEANFILES = \

@ -75,7 +75,7 @@ pkg_files(
], ],
exclude = [ exclude = [
"__init__.py", # not in autotools dist "__init__.py", # not in autotools dist
"BUILD", "BUILD.bazel",
"go/*", "go/*",
], ],
), ),

@ -61,7 +61,7 @@ java_library(
pkg_files( pkg_files(
name = "dist_files", name = "dist_files",
srcs = ["BUILD"], srcs = ["BUILD.bazel"],
strip_prefix = strip_prefix.from_root(""), strip_prefix = strip_prefix.from_root(""),
visibility = ["//benchmarks:__pkg__"], visibility = ["//benchmarks:__pkg__"],
) )

@ -22,6 +22,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenaz_sampler.h" inc
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h" include\google\protobuf\compiler\command_line_interface.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h" include\google\protobuf\compiler\command_line_interface.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\file.h" include\google\protobuf\compiler\cpp\file.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\file.h" include\google\protobuf\compiler\cpp\file.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h" include\google\protobuf\compiler\cpp\cpp_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\generator.h" include\google\protobuf\compiler\cpp\generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\generator.h" include\google\protobuf\compiler\cpp\generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\helpers.h" include\google\protobuf\compiler\cpp\helpers.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\helpers.h" include\google\protobuf\compiler\cpp\helpers.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\names.h" include\google\protobuf\compiler\cpp\names.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\names.h" include\google\protobuf\compiler\cpp\names.h
@ -31,6 +32,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\cshar
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_options.h" include\google\protobuf\compiler\csharp\csharp_options.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_options.h" include\google\protobuf\compiler\csharp\csharp_options.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h" include\google\protobuf\compiler\importer.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h" include\google\protobuf\compiler\importer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\generator.h" include\google\protobuf\compiler\java\generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\generator.h" include\google\protobuf\compiler\java\generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h" include\google\protobuf\compiler\java\java_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\kotlin_generator.h" include\google\protobuf\compiler\java\kotlin_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\kotlin_generator.h" include\google\protobuf\compiler\java\kotlin_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\names.h" include\google\protobuf\compiler\java\names.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\names.h" include\google\protobuf\compiler\java\names.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h" include\google\protobuf\compiler\objectivec\objectivec_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h" include\google\protobuf\compiler\objectivec\objectivec_generator.h
@ -41,6 +43,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" in
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\generator.h" include\google\protobuf\compiler\python\generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\generator.h" include\google\protobuf\compiler\python\generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\pyi_generator.h" include\google\protobuf\compiler\python\pyi_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\pyi_generator.h" include\google\protobuf\compiler\python\pyi_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h" include\google\protobuf\descriptor.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h" include\google\protobuf\descriptor.pb.h

@ -87,6 +87,7 @@ set(libprotoc_files
set(libprotoc_headers set(libprotoc_headers
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/file.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/file.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/helpers.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/helpers.h
@ -96,6 +97,7 @@ set(libprotoc_headers
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_names.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_options.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_options.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/kotlin_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/kotlin_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/names.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.h
@ -104,6 +106,7 @@ set(libprotoc_headers
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.h
) )

@ -28,7 +28,7 @@ filegroup(
pkg_files( pkg_files(
name = "dist_files", name = "dist_files",
srcs = [ srcs = [
"BUILD", "BUILD.bazel",
"README.md", "README.md",
"bom/pom.xml", "bom/pom.xml",
"lite.md", "lite.md",

@ -4,7 +4,7 @@ load("@rules_jvm_external//:defs.bzl", "java_export")
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library")
load("//:internal.bzl", "conformance_test") load("//:internal.bzl", "conformance_test")
load("//:protobuf_version.bzl", "PROTOBUF_VERSION") load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION")
load("//java/internal:testing.bzl", "junit_tests") load("//java/internal:testing.bzl", "junit_tests")
LITE_SRCS = [ LITE_SRCS = [
@ -116,7 +116,7 @@ java_library(
# Bazel users, don't depend on this target, use //java/lite. # Bazel users, don't depend on this target, use //java/lite.
java_export( java_export(
name = "lite_mvn", name = "lite_mvn",
maven_coordinates = "com.google.protobuf:protobuf-javalite:%s" % PROTOBUF_VERSION, maven_coordinates = "com.google.protobuf:protobuf-javalite:%s" % PROTOBUF_JAVA_VERSION,
pom_template = "//java/lite:pom_template.xml", pom_template = "//java/lite:pom_template.xml",
resources = [ resources = [
"//:lite_well_known_protos", "//:lite_well_known_protos",
@ -151,7 +151,7 @@ java_library(
# Bazel users, don't depend on this target, use :core. # Bazel users, don't depend on this target, use :core.
java_export( java_export(
name = "core_mvn", name = "core_mvn",
maven_coordinates = "com.google.protobuf:protobuf-java:%s" % PROTOBUF_VERSION, maven_coordinates = "com.google.protobuf:protobuf-java:%s" % PROTOBUF_JAVA_VERSION,
pom_template = "pom_template.xml", pom_template = "pom_template.xml",
resources = [ resources = [
"//:well_known_protos", "//:well_known_protos",
@ -420,7 +420,7 @@ pkg_files(
"src/test/java/**/*.java", "src/test/java/**/*.java",
"src/test/proto/**/*.proto", "src/test/proto/**/*.proto",
]) + [ ]) + [
"BUILD", "BUILD.bazel",
"generate-sources-build.xml", "generate-sources-build.xml",
"generate-test-sources-build.xml", "generate-test-sources-build.xml",
"pom.xml", "pom.xml",

@ -5,7 +5,7 @@ load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
pkg_files( pkg_files(
name = "dist_files", name = "dist_files",
srcs = [ srcs = [
"BUILD", "BUILD.bazel",
"testing.bzl", "testing.bzl",
], ],
strip_prefix = strip_prefix.from_root(""), strip_prefix = strip_prefix.from_root(""),

@ -2,7 +2,7 @@ load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
load("@rules_java//java:defs.bzl", "java_lite_proto_library") load("@rules_java//java:defs.bzl", "java_lite_proto_library")
load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export") load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export")
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("//:protobuf_version.bzl", "PROTOBUF_VERSION") load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION")
load("//:protobuf.bzl", "internal_gen_kt_protos") load("//:protobuf.bzl", "internal_gen_kt_protos")
java_lite_proto_library( java_lite_proto_library(
@ -34,7 +34,7 @@ kt_jvm_export(
"@com_github_jetbrains_kotlin//:kotlin-stdlib", "@com_github_jetbrains_kotlin//:kotlin-stdlib",
"//java/lite", "//java/lite",
], ],
maven_coordinates = "com.google.protobuf:protobuf-kotlin-lite:%s" % PROTOBUF_VERSION, maven_coordinates = "com.google.protobuf:protobuf-kotlin-lite:%s" % PROTOBUF_JAVA_VERSION,
pom_template = "//java/kotlin-lite:pom_template.xml", pom_template = "//java/kotlin-lite:pom_template.xml",
resources = ["//:well_known_protos"], resources = ["//:well_known_protos"],
runtime_deps = [ runtime_deps = [
@ -191,7 +191,7 @@ pkg_files(
"src/main/kotlin/com/google/protobuf/*.kt", "src/main/kotlin/com/google/protobuf/*.kt",
"src/test/kotlin/**/*.kt", "src/test/kotlin/**/*.kt",
]) + [ ]) + [
"BUILD", "BUILD.bazel",
"generate-sources-build.xml", "generate-sources-build.xml",
"generate-test-sources-build.xml", "generate-test-sources-build.xml",
"lite.awk", "lite.awk",

@ -3,7 +3,7 @@ load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export") load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export")
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("@rules_proto//proto:defs.bzl", "proto_library") load("@rules_proto//proto:defs.bzl", "proto_library")
load("//:protobuf_version.bzl", "PROTOBUF_VERSION") load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION")
load("//:protobuf.bzl", "internal_gen_kt_protos") load("//:protobuf.bzl", "internal_gen_kt_protos")
exports_files([ exports_files([
@ -56,7 +56,7 @@ kt_jvm_export(
"@com_github_jetbrains_kotlin//:kotlin-stdlib", "@com_github_jetbrains_kotlin//:kotlin-stdlib",
"//java/core", "//java/core",
], ],
maven_coordinates = "com.google.protobuf:protobuf-kotlin:%s" % PROTOBUF_VERSION, maven_coordinates = "com.google.protobuf:protobuf-kotlin:%s" % PROTOBUF_JAVA_VERSION,
pom_template = "//java/kotlin:pom_template.xml", pom_template = "//java/kotlin:pom_template.xml",
resources = ["//:well_known_protos"], resources = ["//:well_known_protos"],
runtime_deps = [ runtime_deps = [
@ -303,7 +303,7 @@ pkg_files(
"src/test/kotlin/**/*.kt", "src/test/kotlin/**/*.kt",
"src/test/proto/**/*.proto", "src/test/proto/**/*.proto",
]) + [ ]) + [
"BUILD", "BUILD.bazel",
"generate-sources-build.xml", "generate-sources-build.xml",
"generate-test-sources-build.xml", "generate-test-sources-build.xml",
"pom.xml", "pom.xml",

@ -3,7 +3,6 @@
<mkdir dir="${generated.sources.dir}"/> <mkdir dir="${generated.sources.dir}"/>
<exec executable="${protoc}"> <exec executable="${protoc}">
<arg value="--kotlin_out=${generated.sources.dir}"/> <arg value="--kotlin_out=${generated.sources.dir}"/>
<arg value="--java_out=${generated.sources.dir}"/>
<arg value="--proto_path=${protobuf.source.dir}"/> <arg value="--proto_path=${protobuf.source.dir}"/>
<arg value="${protobuf.source.dir}/google/protobuf/any.proto"/> <arg value="${protobuf.source.dir}/google/protobuf/any.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/api.proto"/> <arg value="${protobuf.source.dir}/google/protobuf/api.proto"/>

@ -83,7 +83,7 @@ pkg_files(
srcs = glob([ srcs = glob([
"**/*.java", "**/*.java",
]) + [ ]) + [
"BUILD", "BUILD.bazel",
"generate-sources-build.xml", "generate-sources-build.xml",
"generate-test-sources-build.xml", "generate-test-sources-build.xml",
"lite.awk", "lite.awk",

@ -2,7 +2,7 @@ load("@rules_java//java:defs.bzl", "java_proto_library")
load("@rules_jvm_external//:defs.bzl", "java_export") load("@rules_jvm_external//:defs.bzl", "java_export")
load("@rules_pkg//:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix") load("@rules_pkg//:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix")
load("@rules_proto//proto:defs.bzl", "proto_library") load("@rules_proto//proto:defs.bzl", "proto_library")
load("//:protobuf_version.bzl", "PROTOBUF_VERSION") load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION")
load("//java/internal:testing.bzl", "junit_tests") load("//java/internal:testing.bzl", "junit_tests")
java_library( java_library(
@ -25,7 +25,7 @@ java_library(
java_export( java_export(
name = "util_mvn", name = "util_mvn",
deploy_env = ["//java/core"], deploy_env = ["//java/core"],
maven_coordinates = "com.google.protobuf:protobuf-java-util:%s" % PROTOBUF_VERSION, maven_coordinates = "com.google.protobuf:protobuf-java-util:%s" % PROTOBUF_JAVA_VERSION,
pom_template = "pom_template.xml", pom_template = "pom_template.xml",
visibility = ["//java:__pkg__"], visibility = ["//java:__pkg__"],
runtime_deps = [":util"], runtime_deps = [":util"],
@ -83,7 +83,7 @@ pkg_files(
"src/test/**/*.java", "src/test/**/*.java",
"src/test/**/*.proto", "src/test/**/*.proto",
]) + [ ]) + [
"BUILD", "BUILD.bazel",
"pom.xml", "pom.xml",
"pom_template.xml", "pom_template.xml",
], ],

@ -1,11 +0,0 @@
#!/bin/bash
#
# Build file to set up and run tests
# Change to repo root
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
source kokoro/macos/prepare_build_macos_rc
./tests.sh objectivec_cocoapods_integration

@ -1,5 +0,0 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/macos/objectivec_cocoapods_integration/build.sh"
timeout_mins: 1440

@ -1,5 +0,0 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/macos/objectivec_cocoapods_integration/build.sh"
timeout_mins: 1440

@ -1,290 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
F4D5A0AE1CEE2D8F00562D79 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A0AD1CEE2D8F00562D79 /* AppDelegate.m */; };
F4D5A0B11CEE2D8F00562D79 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A0B01CEE2D8F00562D79 /* main.m */; };
F4D5A0B31CEE2D8F00562D79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0B21CEE2D8F00562D79 /* Assets.xcassets */; };
F4D5A0B61CEE2D8F00562D79 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0B41CEE2D8F00562D79 /* MainMenu.xib */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F4D5A0A91CEE2D8F00562D79 /* OSXCocoaPodsTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSXCocoaPodsTester.app; sourceTree = BUILT_PRODUCTS_DIR; };
F4D5A0AC1CEE2D8F00562D79 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
F4D5A0AD1CEE2D8F00562D79 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
F4D5A0B01CEE2D8F00562D79 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
F4D5A0B21CEE2D8F00562D79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F4D5A0B51CEE2D8F00562D79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
F4D5A0B71CEE2D8F00562D79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F4D5A0A61CEE2D8F00562D79 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F4D5A0A01CEE2D8F00562D79 = {
isa = PBXGroup;
children = (
F4D5A0AB1CEE2D8F00562D79 /* OSXCocoaPodsTester */,
F4D5A0AA1CEE2D8F00562D79 /* Products */,
);
sourceTree = "<group>";
};
F4D5A0AA1CEE2D8F00562D79 /* Products */ = {
isa = PBXGroup;
children = (
F4D5A0A91CEE2D8F00562D79 /* OSXCocoaPodsTester.app */,
);
name = Products;
sourceTree = "<group>";
};
F4D5A0AB1CEE2D8F00562D79 /* OSXCocoaPodsTester */ = {
isa = PBXGroup;
children = (
F4D5A0AC1CEE2D8F00562D79 /* AppDelegate.h */,
F4D5A0AD1CEE2D8F00562D79 /* AppDelegate.m */,
F4D5A0B21CEE2D8F00562D79 /* Assets.xcassets */,
F4D5A0B41CEE2D8F00562D79 /* MainMenu.xib */,
F4D5A0B71CEE2D8F00562D79 /* Info.plist */,
F4D5A0AF1CEE2D8F00562D79 /* Supporting Files */,
);
path = OSXCocoaPodsTester;
sourceTree = "<group>";
};
F4D5A0AF1CEE2D8F00562D79 /* Supporting Files */ = {
isa = PBXGroup;
children = (
F4D5A0B01CEE2D8F00562D79 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F4D5A0A81CEE2D8F00562D79 /* OSXCocoaPodsTester */ = {
isa = PBXNativeTarget;
buildConfigurationList = F4D5A0BA1CEE2D8F00562D79 /* Build configuration list for PBXNativeTarget "OSXCocoaPodsTester" */;
buildPhases = (
F4D5A0A51CEE2D8F00562D79 /* Sources */,
F4D5A0A61CEE2D8F00562D79 /* Frameworks */,
F4D5A0A71CEE2D8F00562D79 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = OSXCocoaPodsTester;
productName = OSXCocoaPodsTester;
productReference = F4D5A0A91CEE2D8F00562D79 /* OSXCocoaPodsTester.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F4D5A0A11CEE2D8F00562D79 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = Google;
TargetAttributes = {
F4D5A0A81CEE2D8F00562D79 = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = F4D5A0A41CEE2D8F00562D79 /* Build configuration list for PBXProject "OSXCocoaPodsTester" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F4D5A0A01CEE2D8F00562D79;
productRefGroup = F4D5A0AA1CEE2D8F00562D79 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F4D5A0A81CEE2D8F00562D79 /* OSXCocoaPodsTester */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F4D5A0A71CEE2D8F00562D79 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4D5A0B31CEE2D8F00562D79 /* Assets.xcassets in Resources */,
F4D5A0B61CEE2D8F00562D79 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F4D5A0A51CEE2D8F00562D79 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4D5A0B11CEE2D8F00562D79 /* main.m in Sources */,
F4D5A0AE1CEE2D8F00562D79 /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
F4D5A0B41CEE2D8F00562D79 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
F4D5A0B51CEE2D8F00562D79 /* Base */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
F4D5A0B81CEE2D8F00562D79 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
F4D5A0B91CEE2D8F00562D79 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
F4D5A0BB1CEE2D8F00562D79 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = OSXCocoaPodsTester/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.google.OSXCocoaPodsTester;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
F4D5A0BC1CEE2D8F00562D79 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = OSXCocoaPodsTester/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.google.OSXCocoaPodsTester;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F4D5A0A41CEE2D8F00562D79 /* Build configuration list for PBXProject "OSXCocoaPodsTester" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4D5A0B81CEE2D8F00562D79 /* Debug */,
F4D5A0B91CEE2D8F00562D79 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F4D5A0BA1CEE2D8F00562D79 /* Build configuration list for PBXNativeTarget "OSXCocoaPodsTester" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4D5A0BB1CEE2D8F00562D79 /* Debug */,
F4D5A0BC1CEE2D8F00562D79 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = F4D5A0A11CEE2D8F00562D79 /* Project object */;
}

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:OSXCocoaPodsTester.xcodeproj">
</FileRef>
</Workspace>

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
BuildableName = "OSXCocoaPodsTester.app"
BlueprintName = "OSXCocoaPodsTester"
ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
BuildableName = "OSXCocoaPodsTester.app"
BlueprintName = "OSXCocoaPodsTester"
ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
BuildableName = "OSXCocoaPodsTester.app"
BlueprintName = "OSXCocoaPodsTester"
ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
BuildableName = "OSXCocoaPodsTester.app"
BlueprintName = "OSXCocoaPodsTester"
ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -1,37 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end

@ -1,48 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import "AppDelegate.h"
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end

@ -1,58 +0,0 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -1,680 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6233" systemVersion="14A329f" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6233"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider="">
<connections>
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="OSXCocoaPodsTester" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="OSXCocoaPodsTester" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About OSXCocoaPodsTester" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide OSXCocoaPodsTester" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit OSXCocoaPodsTester" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
<connections>
<action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="tXI-mr-wws">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
<items>
<menuItem title="Clear Menu" id="vNY-rz-j42">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
<connections>
<action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
<connections>
<action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" id="KaW-ft-85H">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
<connections>
<action selector="print:" target="-1" id="qaZ-4w-aoO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Format" id="jxT-CU-nIS">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
<items>
<menuItem title="Font" id="Gi5-1S-RQB">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
<items>
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
<connections>
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
</connections>
</menuItem>
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
</connections>
</menuItem>
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
</connections>
</menuItem>
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
<connections>
<action selector="underline:" target="-1" id="FYS-2b-JAY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
</connections>
</menuItem>
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
<menuItem title="Kern" id="jBQ-r6-VK2">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
<items>
<menuItem title="Use Default" id="GUa-eO-cwY">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
</connections>
</menuItem>
<menuItem title="Use None" id="cDB-IK-hbR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
</connections>
</menuItem>
<menuItem title="Tighten" id="46P-cB-AYj">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
</connections>
</menuItem>
<menuItem title="Loosen" id="ogc-rX-tC1">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Ligatures" id="o6e-r0-MWq">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
<items>
<menuItem title="Use Default" id="agt-UL-0e3">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
</connections>
</menuItem>
<menuItem title="Use None" id="J7y-lM-qPV">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
</connections>
</menuItem>
<menuItem title="Use All" id="xQD-1f-W4t">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Baseline" id="OaQ-X3-Vso">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
<items>
<menuItem title="Use Default" id="3Om-Ey-2VK">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
</connections>
</menuItem>
<menuItem title="Superscript" id="Rqc-34-cIF">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
</connections>
</menuItem>
<menuItem title="Subscript" id="I0S-gh-46l">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
</connections>
</menuItem>
<menuItem title="Raise" id="2h7-ER-AoG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
</connections>
</menuItem>
<menuItem title="Lower" id="1tx-W0-xDw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
<connections>
<action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
</connections>
</menuItem>
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Text" id="Fal-I4-PZk">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Text" id="d9c-me-L2H">
<items>
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
<connections>
<action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
</connections>
</menuItem>
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
<connections>
<action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
</connections>
</menuItem>
<menuItem title="Justify" id="J5U-5w-g23">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
</connections>
</menuItem>
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
<connections>
<action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
<menuItem title="Writing Direction" id="H1b-Si-o9J">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
<items>
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="YGs-j5-SAR">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
</connections>
</menuItem>
<menuItem id="Lbh-J2-qVU">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
</connections>
</menuItem>
<menuItem id="jFq-tB-4Kx">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="Nop-cj-93Q">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
</connections>
</menuItem>
<menuItem id="BgM-ve-c93">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
</connections>
</menuItem>
<menuItem id="RB4-Sm-HuC">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
<menuItem title="Show Ruler" id="vLm-3I-IUL">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
</connections>
</menuItem>
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
</connections>
</menuItem>
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="OSXCocoaPodsTester Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<window title="OSXCocoaPodsTester" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
<view key="contentView" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</window>
</objects>
</document>

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Google. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

@ -1,35 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
return NSApplicationMain(argc, argv);
}

@ -1,10 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :osx, '10.9'
install! 'cocoapods', :deterministic_uuids => false
use_frameworks!
target 'OSXCocoaPodsTester' do
pod 'Protobuf', :path => '../../../..'
end

@ -1,8 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :osx, '10.9'
install! 'cocoapods', :deterministic_uuids => false
target 'OSXCocoaPodsTester' do
pod 'Protobuf', :path => '../../../..'
end

@ -1,9 +0,0 @@
CocoaPods Protocol Buffers Integration Tests
============================================
The sub directories are the basic projects as created by Xcode 6.3. They are
used to then drive `pod` and `xcodebuild` to ensure things integrate/build
as expected.
`run_tests.sh` defaults to running all the tests, invoke it with `--help` to
see the arguments to control what tests are run.

@ -1,10 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
install! 'cocoapods', :deterministic_uuids => false
use_frameworks!
target 'iOSCocoaPodsTester' do
pod 'Protobuf', :path => '../../../..'
end

@ -1,8 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
install! 'cocoapods', :deterministic_uuids => false
target 'iOSCocoaPodsTester' do
pod 'Protobuf', :path => '../../../..'
end

@ -1,309 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
F4D5A08B1CEE01E200562D79 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A08A1CEE01E200562D79 /* main.m */; };
F4D5A08E1CEE01E200562D79 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A08D1CEE01E200562D79 /* AppDelegate.m */; };
F4D5A0911CEE01E200562D79 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A0901CEE01E200562D79 /* ViewController.m */; };
F4D5A0941CEE01E200562D79 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0921CEE01E200562D79 /* Main.storyboard */; };
F4D5A0961CEE01E200562D79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0951CEE01E200562D79 /* Assets.xcassets */; };
F4D5A0991CEE01E200562D79 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0971CEE01E200562D79 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F4D5A0861CEE01E200562D79 /* iOSCocoaPodsTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSCocoaPodsTester.app; sourceTree = BUILT_PRODUCTS_DIR; };
F4D5A08A1CEE01E200562D79 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
F4D5A08C1CEE01E200562D79 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
F4D5A08D1CEE01E200562D79 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
F4D5A08F1CEE01E200562D79 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
F4D5A0901CEE01E200562D79 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
F4D5A0931CEE01E200562D79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
F4D5A0951CEE01E200562D79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F4D5A0981CEE01E200562D79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F4D5A09A1CEE01E200562D79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F4D5A0831CEE01E200562D79 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F4D5A07D1CEE01E200562D79 = {
isa = PBXGroup;
children = (
F4D5A0881CEE01E200562D79 /* iOSCocoaPodsTester */,
F4D5A0871CEE01E200562D79 /* Products */,
);
sourceTree = "<group>";
};
F4D5A0871CEE01E200562D79 /* Products */ = {
isa = PBXGroup;
children = (
F4D5A0861CEE01E200562D79 /* iOSCocoaPodsTester.app */,
);
name = Products;
sourceTree = "<group>";
};
F4D5A0881CEE01E200562D79 /* iOSCocoaPodsTester */ = {
isa = PBXGroup;
children = (
F4D5A08C1CEE01E200562D79 /* AppDelegate.h */,
F4D5A08D1CEE01E200562D79 /* AppDelegate.m */,
F4D5A08F1CEE01E200562D79 /* ViewController.h */,
F4D5A0901CEE01E200562D79 /* ViewController.m */,
F4D5A0921CEE01E200562D79 /* Main.storyboard */,
F4D5A0951CEE01E200562D79 /* Assets.xcassets */,
F4D5A0971CEE01E200562D79 /* LaunchScreen.storyboard */,
F4D5A09A1CEE01E200562D79 /* Info.plist */,
F4D5A0891CEE01E200562D79 /* Supporting Files */,
);
path = iOSCocoaPodsTester;
sourceTree = "<group>";
};
F4D5A0891CEE01E200562D79 /* Supporting Files */ = {
isa = PBXGroup;
children = (
F4D5A08A1CEE01E200562D79 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F4D5A0851CEE01E200562D79 /* iOSCocoaPodsTester */ = {
isa = PBXNativeTarget;
buildConfigurationList = F4D5A09D1CEE01E200562D79 /* Build configuration list for PBXNativeTarget "iOSCocoaPodsTester" */;
buildPhases = (
F4D5A0821CEE01E200562D79 /* Sources */,
F4D5A0831CEE01E200562D79 /* Frameworks */,
F4D5A0841CEE01E200562D79 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = iOSCocoaPodsTester;
productName = iOSCocoaPodsTester;
productReference = F4D5A0861CEE01E200562D79 /* iOSCocoaPodsTester.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F4D5A07E1CEE01E200562D79 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = Google;
TargetAttributes = {
F4D5A0851CEE01E200562D79 = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = F4D5A0811CEE01E200562D79 /* Build configuration list for PBXProject "iOSCocoaPodsTester" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F4D5A07D1CEE01E200562D79;
productRefGroup = F4D5A0871CEE01E200562D79 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
F4D5A0851CEE01E200562D79 /* iOSCocoaPodsTester */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
F4D5A0841CEE01E200562D79 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4D5A0991CEE01E200562D79 /* LaunchScreen.storyboard in Resources */,
F4D5A0961CEE01E200562D79 /* Assets.xcassets in Resources */,
F4D5A0941CEE01E200562D79 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F4D5A0821CEE01E200562D79 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4D5A0911CEE01E200562D79 /* ViewController.m in Sources */,
F4D5A08E1CEE01E200562D79 /* AppDelegate.m in Sources */,
F4D5A08B1CEE01E200562D79 /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
F4D5A0921CEE01E200562D79 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
F4D5A0931CEE01E200562D79 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
F4D5A0971CEE01E200562D79 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
F4D5A0981CEE01E200562D79 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
F4D5A09B1CEE01E200562D79 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
F4D5A09C1CEE01E200562D79 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
F4D5A09E1CEE01E200562D79 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = iOSCocoaPodsTester/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.google.iOSCocoaPodsTester;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
F4D5A09F1CEE01E200562D79 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = iOSCocoaPodsTester/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.google.iOSCocoaPodsTester;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F4D5A0811CEE01E200562D79 /* Build configuration list for PBXProject "iOSCocoaPodsTester" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4D5A09B1CEE01E200562D79 /* Debug */,
F4D5A09C1CEE01E200562D79 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F4D5A09D1CEE01E200562D79 /* Build configuration list for PBXNativeTarget "iOSCocoaPodsTester" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4D5A09E1CEE01E200562D79 /* Debug */,
F4D5A09F1CEE01E200562D79 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = F4D5A07E1CEE01E200562D79 /* Project object */;
}

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:iOSCocoaPodsTester.xcodeproj">
</FileRef>
</Workspace>

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
BuildableName = "iOSCocoaPodsTester.app"
BlueprintName = "iOSCocoaPodsTester"
ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
BuildableName = "iOSCocoaPodsTester.app"
BlueprintName = "iOSCocoaPodsTester"
ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
BuildableName = "iOSCocoaPodsTester.app"
BlueprintName = "iOSCocoaPodsTester"
ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
BuildableName = "iOSCocoaPodsTester.app"
BlueprintName = "iOSCocoaPodsTester"
ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -1,39 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

@ -1,67 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

@ -1,68 +0,0 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

@ -1,37 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

@ -1,49 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end

@ -1,39 +0,0 @@
//
// Protocol Buffers - Google's data interchange format
// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

@ -1,150 +0,0 @@
#!/bin/bash
#
# Helper to run the pods tests.
set -eu
readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
printUsage() {
NAME=$(basename "${0}")
cat << EOF
usage: ${NAME} [OPTIONS]
This script runs some test to check the CocoaPods integration.
OPTIONS:
General:
-h, --help
Show this message
--skip-static
Skip the static based pods tests.
--skip-framework
Skip the framework based pods tests.
--skip-ios
Skip the iOS pods tests.
--skip-osx
Skip the OS X pods tests.
EOF
}
TEST_MODES=( "static" "framework" )
TEST_NAMES=( "iOSCocoaPodsTester" "OSXCocoaPodsTester" )
while [[ $# != 0 ]]; do
case "${1}" in
-h | --help )
printUsage
exit 0
;;
--skip-static )
TEST_MODES=(${TEST_MODES[@]/static})
;;
--skip-framework )
TEST_MODES=(${TEST_MODES[@]/framework})
;;
--skip-ios )
TEST_NAMES=(${TEST_NAMES[@]/iOSCocoaPodsTester})
;;
--skip-osx )
TEST_NAMES=(${TEST_NAMES[@]/OSXCocoaPodsTester})
;;
-*)
echo "ERROR: Unknown option: ${1}" 1>&2
printUsage
exit 1
;;
*)
echo "ERROR: Unknown argument: ${1}" 1>&2
printUsage
exit 1
;;
esac
shift
done
# Sanity check.
if [[ "${#TEST_NAMES[@]}" == 0 ]] ; then
echo "ERROR: Need to run at least iOS or OS X tests." 1>&2
exit 2
fi
if [[ "${#TEST_MODES[@]}" == 0 ]] ; then
echo "ERROR: Need to run at least static or frameworks tests." 1>&2
exit 2
fi
header() {
echo ""
echo "========================================================================"
echo " ${@}"
echo "========================================================================"
echo ""
}
# Cleanup hook for do_test, assumes directory is correct.
cleanup() {
local TEST_NAME="$1"
echo "Cleaning up..."
# Generally don't let things fail, and eat common stdout, but let stderr show
# in case something does hiccup.
xcodebuild -workspace "${TEST_NAME}.xcworkspace" -scheme "${TEST_NAME}" clean > /dev/null || true
pod deintegrate > /dev/null || true
# Flush the cache so nothing is left behind.
pod cache clean --all || true
# Delete the files left after pod deintegrate.
rm -f Podfile.lock || true
rm -rf "${TEST_NAME}.xcworkspace" || true
git checkout -- "${TEST_NAME}.xcodeproj" || true
# Remove the Podfile that was put in place.
rm -f Podfile || true
}
do_test() {
local TEST_NAME="$1"
local TEST_MODE="$2"
header "${TEST_NAME}" - Mode: "${TEST_MODE}"
cd "${ScriptDir}/${TEST_NAME}"
# Hook in cleanup for any failures.
trap "cleanup ${TEST_NAME}" EXIT
# Ensure nothing is cached by pods to start with that could throw things off.
pod cache clean --all
# Put the right Podfile in place.
cp -f "Podfile-${TEST_MODE}" "Podfile"
xcodebuild_args=( "-workspace" "${TEST_NAME}.xcworkspace" "-scheme" "${TEST_NAME}" )
# For iOS, if the SDK is not provided it tries to use iphoneos, and the test
# fail on Travis since those machines don't have a Code Signing identity.
if [[ "${TEST_NAME}" == iOS* ]] ; then
# Apparently the destination flag is required to avoid "Unsupported architecture"
# errors.
xcodebuild_args+=(
-sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
-destination "platform=iOS Simulator,name=iPad 2,OS=9.3"
)
fi
# Do the work!
pod install --verbose
xcodebuild "${xcodebuild_args[@]}" build
# Clear the hook and manually run cleanup.
trap - EXIT
cleanup "${TEST_NAME}"
}
# Run the tests.
for TEST_NAME in "${TEST_NAMES[@]}" ; do
for TEST_MODE in "${TEST_MODES[@]}" ; do
do_test "${TEST_NAME}" "${TEST_MODE}"
done
done

@ -6,6 +6,7 @@ load(
"pkg_files", "pkg_files",
) )
load("//:protobuf_release.bzl", "package_naming") load("//:protobuf_release.bzl", "package_naming")
load(":build_systems.bzl", "gen_automake_file_lists", "gen_file_lists")
load(":cc_dist_library.bzl", "cc_dist_library") load(":cc_dist_library.bzl", "cc_dist_library")
package_naming( package_naming(
@ -308,6 +309,44 @@ pkg_zip(
package_variables = ":protobuf_pkg_naming", package_variables = ":protobuf_pkg_naming",
) )
################################################################################
# Generated file lists for build systems
################################################################################
gen_file_lists(
name = "gen_src_file_lists",
testonly = 1,
out_stem = "src_file_lists",
src_libs = {
# source rule: name in generated file
"//:protobuf": "libprotobuf",
"//:protoc_lib": "libprotoc",
"//:protobuf_lite": "libprotobuf_lite",
},
)
gen_automake_file_lists(
name = "gen_automake_extra_dist_lists",
testonly = 1,
out = "extra_dist_file_lists.am",
src_libs = {
# source rule: name in generated file
"//:common_dist_files": "dist_common",
"//:conformance_dist_files": "dist_conformance",
"//benchmarks:all_dist_files": "dist_benchmark",
"@com_google_protobuf_examples//:dist_files": "dist_example",
"//:csharp_dist_files": "dist_csharp",
"//csharp:dist_files": "dist_csharp2",
"//:objectivec_dist_files": "dist_objectivec",
"//objectivec:dist_files": "dist_objectivec2",
"//:php_dist_files": "dist_php",
"//php:dist_files": "dist_php2",
"//:python_dist_files": "dist_python",
"//ruby:dist_files": "dist_ruby",
"//js:dist_files": "dist_js",
},
)
################################################################################ ################################################################################
# Protobuf runtime libraries. # Protobuf runtime libraries.
################################################################################ ################################################################################

@ -0,0 +1,452 @@
# Starlark utilities for working with other build systems
load("@rules_pkg//:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo")
################################################################################
# Macro to create CMake and Automake source lists.
################################################################################
def gen_file_lists(name, out_stem, **kwargs):
gen_cmake_file_lists(
name = name + "_cmake",
out = out_stem + ".cmake",
source_prefix = "${protobuf_SOURCE_DIR}/",
**kwargs
)
gen_automake_file_lists(
name = name + "_automake",
out = out_stem + ".am",
source_prefix = "$(top_srcdir)/",
**kwargs
)
native.filegroup(
name = name,
srcs = [
out_stem + ".cmake",
out_stem + ".am",
],
)
################################################################################
# Aspect that extracts srcs, hdrs, etc.
################################################################################
CcFileList = provider(
doc = "List of files to be built into a library.",
fields = {
# As a rule of thumb, `hdrs` and `textual_hdrs` are the files that
# would be installed along with a prebuilt library.
"hdrs": "public header files, including those used by generated code",
"textual_hdrs": "files which are included but are not self-contained",
# The `internal_hdrs` are header files which appear in `srcs`.
# These are only used when compiling the library.
"internal_hdrs": "internal header files (only used to build .cc files)",
"srcs": "source files",
},
)
ProtoFileList = provider(
doc = "List of proto files and generated code to be built into a library.",
fields = {
# Proto files:
"proto_srcs": "proto file sources",
# Generated sources:
"hdrs": "header files that are expected to be generated",
"srcs": "source files that are expected to be generated",
},
)
def _flatten_target_files(targets):
files = []
for target in targets:
for tfile in target.files.to_list():
files.append(tfile)
return files
def _combine_cc_file_lists(file_lists):
hdrs = {}
textual_hdrs = {}
internal_hdrs = {}
srcs = {}
for file_list in file_lists:
hdrs.update({f: 1 for f in file_list.hdrs})
textual_hdrs.update({f: 1 for f in file_list.textual_hdrs})
internal_hdrs.update({f: 1 for f in file_list.internal_hdrs})
srcs.update({f: 1 for f in file_list.srcs})
return CcFileList(
hdrs = sorted(hdrs.keys()),
textual_hdrs = sorted(textual_hdrs.keys()),
internal_hdrs = sorted(internal_hdrs.keys()),
srcs = sorted(srcs.keys()),
)
def _file_list_aspect_impl(target, ctx):
# We're going to reach directly into the attrs on the traversed rule.
rule_attr = ctx.rule.attr
providers = []
# Extract sources from a `cc_library` (or similar):
if CcInfo in target:
# CcInfo is a proxy for what we expect this rule to look like.
# However, some deps may expose `CcInfo` without having `srcs`,
# `hdrs`, etc., so we use `getattr` to handle that gracefully.
internal_hdrs = []
srcs = []
# Filter `srcs` so it only contains source files. Headers will go
# into `internal_headers`.
for src in _flatten_target_files(getattr(rule_attr, "srcs", [])):
if src.extension.lower() in ["c", "cc", "cpp", "cxx"]:
srcs.append(src)
else:
internal_hdrs.append(src)
providers.append(CcFileList(
hdrs = _flatten_target_files(getattr(rule_attr, "hdrs", [])),
textual_hdrs = _flatten_target_files(getattr(
rule_attr,
"textual_hdrs",
[],
)),
internal_hdrs = internal_hdrs,
srcs = srcs,
))
# Extract sources from a `proto_library`:
if ProtoInfo in target:
proto_srcs = []
srcs = []
hdrs = []
for src in _flatten_target_files(rule_attr.srcs):
proto_srcs.append(src)
srcs.append("%s/%s.pb.cc" % (src.dirname, src.basename))
hdrs.append("%s/%s.pb.h" % (src.dirname, src.basename))
providers.append(ProtoFileList(
proto_srcs = proto_srcs,
srcs = srcs,
hdrs = hdrs,
))
return providers
file_list_aspect = aspect(
doc = """
Aspect to provide the list of sources and headers from a rule.
Output is CcFileList and/or ProtoFileList. Example:
cc_library(
name = "foo",
srcs = [
"foo.cc",
"foo_internal.h",
],
hdrs = ["foo.h"],
textual_hdrs = ["foo_inl.inc"],
)
# produces:
# CcFileList(
# hdrs = [File("foo.h")],
# textual_hdrs = [File("foo_inl.inc")],
# internal_hdrs = [File("foo_internal.h")],
# srcs = [File("foo.cc")],
# )
proto_library(
name = "bar_proto",
srcs = ["bar.proto"],
)
# produces:
# ProtoFileList(
# proto_srcs = ["bar.proto"],
# # Generated filenames are synthesized:
# hdrs = ["bar.pb.h"],
# srcs = ["bar.pb.cc"],
# )
""",
implementation = _file_list_aspect_impl,
)
################################################################################
# Generic source lists generation
#
# This factory creates a rule implementation that is parameterized by a
# fragment generator function.
################################################################################
def _create_file_list_impl(fragment_generator):
# `fragment_generator` is a function like:
# def fn(originating_rule: Label,
# varname: str,
# source_prefix: str,
# path_strings: [str]) -> str
#
# It returns a string that defines `varname` to `path_strings`, each
# prepended with `source_prefix`.
#
# When dealing with `File` objects, the `short_path` is used to strip
# the output prefix for generated files.
def _impl(ctx):
out = ctx.outputs.out
fragments = []
for srcrule, libname in ctx.attr.src_libs.items():
if CcFileList in srcrule:
cc_file_list = srcrule[CcFileList]
fragments.extend([
fragment_generator(
srcrule.label,
libname + "_srcs",
ctx.attr.source_prefix,
[f.short_path for f in cc_file_list.srcs],
),
fragment_generator(
srcrule.label,
libname + "_hdrs",
ctx.attr.source_prefix,
[f.short_path for f in (cc_file_list.hdrs +
cc_file_list.textual_hdrs)],
),
])
if ProtoFileList in srcrule:
proto_file_list = srcrule[ProtoFileList]
fragments.extend([
fragment_generator(
srcrule.label,
libname + "_proto_srcs",
ctx.attr.source_prefix,
[f.short_path for f in proto_file_list.proto_srcs],
),
fragment_generator(
srcrule.label,
libname + "_srcs",
ctx.attr.source_prefix,
proto_file_list.srcs,
),
fragment_generator(
srcrule.label,
libname + "_hdrs",
ctx.attr.source_prefix,
proto_file_list.hdrs,
),
])
files = {}
if PackageFilegroupInfo in srcrule:
for pkg_files_info, origin in srcrule[PackageFilegroupInfo].pkg_files:
# keys are the destination path:
files.update(pkg_files_info.dest_src_map)
if PackageFilesInfo in srcrule:
# keys are the destination:
files.update(srcrule[PackageFilesInfo].dest_src_map)
if files == {} and DefaultInfo in srcrule and CcInfo not in srcrule:
# This could be an individual file or filegroup.
# We explicitly ignore rules with CcInfo, since their
# output artifacts are libraries or binaries.
files.update(
{
f.short_path: 1
for f in srcrule[DefaultInfo].files.to_list()
},
)
if files:
fragments.append(
fragment_generator(
srcrule.label,
libname + "_files",
ctx.attr.source_prefix,
sorted(files.keys()),
),
)
ctx.actions.write(
output = out,
content = (ctx.attr._header % ctx.label) + "\n".join(fragments),
)
return [DefaultInfo(files = depset([out]))]
return _impl
# Common rule attrs for rules that use `_create_file_list_impl`:
# (note that `_header` is also required)
_source_list_common_attrs = {
"out": attr.output(
doc = (
"The generated filename. This should usually have a build " +
"system-specific extension, like `out.am` or `out.cmake`."
),
mandatory = True,
),
"src_libs": attr.label_keyed_string_dict(
doc = (
"A dict, {target: libname} of libraries to include. " +
"Targets can be C++ rules (like `cc_library` or `cc_test`), " +
"`proto_library` rules, files, `filegroup` rules, `pkg_files` " +
"rules, or `pkg_filegroup` rules. " +
"The libname is a string, and used to construct the variable " +
"name in the `out` file holding the target's sources. " +
"For generated files, the output root (like `bazel-bin/`) is not " +
"included. " +
"For `pkg_files` and `pkg_filegroup` rules, the destination path " +
"is used."
),
mandatory = True,
providers = [
[CcFileList],
[DefaultInfo],
[PackageFilegroupInfo],
[PackageFilesInfo],
[ProtoFileList],
],
aspects = [file_list_aspect],
),
"source_prefix": attr.string(
doc = "String to prepend to each source path.",
),
}
################################################################################
# CMake source lists generation
################################################################################
def _cmake_var_fragment(owner, varname, prefix, entries):
"""Returns a single `set(varname ...)` fragment (CMake syntax).
Args:
owner: Label, the rule that owns these srcs.
varname: str, the var name to set.
prefix: str, prefix to prepend to each of `entries`.
entries: [str], the entries in the list.
Returns:
A string.
"""
return (
"# {owner}\n" +
"set({varname}\n" +
"{entries}\n" +
")\n"
).format(
owner = owner,
varname = varname,
entries = "\n".join([" %s%s" % (prefix, f) for f in entries]),
)
gen_cmake_file_lists = rule(
doc = """
Generates a CMake-syntax file with lists of files.
The generated file defines variables with lists of files from `srcs`. The
intent is for these files to be included from a non-generated CMake file
which actually defines the libraries based on these lists.
For C++ rules, the following are generated:
{libname}_srcs: contains srcs.
{libname}_hdrs: contains hdrs and textual_hdrs.
For proto_library, the following are generated:
{libname}_proto_srcs: contains the srcs from the `proto_library` rule.
{libname}_srcs: contains syntesized paths for generated C++ sources.
{libname}_hdrs: contains syntesized paths for generated C++ headers.
""",
implementation = _create_file_list_impl(_cmake_var_fragment),
attrs = dict(
_source_list_common_attrs,
_header = attr.string(
default = """\
# Auto-generated by %s
#
# This file contains lists of sources based on Bazel rules. It should
# be included from a hand-written CMake file that defines targets.
#
# Changes to this file will be overwritten based on Bazel definitions.
if(${CMAKE_VERSION} VERSION_GREATER 3.10 OR ${CMAKE_VERSION} VERSION_EQUAL 3.10)
include_guard()
endif()
""",
),
),
)
################################################################################
# Automake source lists generation
################################################################################
def _automake_var_fragment(owner, varname, prefix, entries):
"""Returns a single variable assignment fragment (Automake syntax).
Args:
owner: Label, the rule that owns these srcs.
varname: str, the var name to set.
prefix: str, prefix to prepend to each of `entries`.
entries: [str], the entries in the list.
Returns:
A string.
"""
if len(entries) == 0:
# A backslash followed by a blank line is illegal. We still want
# to emit the variable, though.
return "# {owner}\n{varname} =\n".format(
owner = owner,
varname = varname,
)
fragment = (
"# {owner}\n" +
"{varname} = \\\n" +
"{entries}"
).format(
owner = owner,
varname = varname,
entries = " \\\n".join([" %s%s" % (prefix, f) for f in entries]),
)
return fragment.rstrip("\\ ") + "\n"
gen_automake_file_lists = rule(
doc = """
Generates an Automake-syntax file with lists of files.
The generated file defines variables with lists of files from `srcs`. The
intent is for these files to be included from a non-generated Makefile.am
file which actually defines the libraries based on these lists.
For C++ rules, the following are generated:
{libname}_srcs: contains srcs.
{libname}_hdrs: contains hdrs and textual_hdrs.
For proto_library, the following are generated:
{libname}_proto_srcs: contains the srcs from the `proto_library` rule.
{libname}_srcs: contains syntesized paths for generated C++ sources.
{libname}_hdrs: contains syntesized paths for generated C++ headers.
""",
implementation = _create_file_list_impl(_automake_var_fragment),
attrs = dict(
_source_list_common_attrs.items(),
_header = attr.string(
default = """\
# Auto-generated by %s
#
# This file contains lists of sources based on Bazel rules. It should
# be included from a hand-written Makefile.am that defines targets.
#
# Changes to this file will be overwritten based on Bazel definitions.
""",
),
),
)

@ -37,8 +37,6 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <memory>
#include <google/protobuf/pyext/message.h> #include <google/protobuf/pyext/message.h>
namespace google { namespace google {

@ -35,7 +35,6 @@
#include <Python.h> #include <Python.h>
#include <cstdint> #include <cstdint>
#include <memory>
#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h> #include <google/protobuf/message.h>

@ -37,10 +37,6 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <memory>
#include <string>
#include <vector>
#include <google/protobuf/pyext/message.h> #include <google/protobuf/pyext/message.h>
namespace google { namespace google {

@ -37,8 +37,6 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <memory>
#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.h>
#include <google/protobuf/pyext/message.h> #include <google/protobuf/pyext/message.h>

@ -74,6 +74,7 @@ nobase_include_HEADERS = \
google/protobuf/arenaz_sampler.h \ google/protobuf/arenaz_sampler.h \
google/protobuf/compiler/code_generator.h \ google/protobuf/compiler/code_generator.h \
google/protobuf/compiler/command_line_interface.h \ google/protobuf/compiler/command_line_interface.h \
google/protobuf/compiler/cpp/cpp_generator.h \
google/protobuf/compiler/cpp/file.h \ google/protobuf/compiler/cpp/file.h \
google/protobuf/compiler/cpp/generator.h \ google/protobuf/compiler/cpp/generator.h \
google/protobuf/compiler/cpp/helpers.h \ google/protobuf/compiler/cpp/helpers.h \
@ -84,6 +85,7 @@ nobase_include_HEADERS = \
google/protobuf/compiler/csharp/csharp_options.h \ google/protobuf/compiler/csharp/csharp_options.h \
google/protobuf/compiler/importer.h \ google/protobuf/compiler/importer.h \
google/protobuf/compiler/java/generator.h \ google/protobuf/compiler/java/generator.h \
google/protobuf/compiler/java/java_generator.h \
google/protobuf/compiler/java/kotlin_generator.h \ google/protobuf/compiler/java/kotlin_generator.h \
google/protobuf/compiler/java/names.h \ google/protobuf/compiler/java/names.h \
google/protobuf/compiler/objectivec/objectivec_generator.h \ google/protobuf/compiler/objectivec/objectivec_generator.h \
@ -94,6 +96,7 @@ nobase_include_HEADERS = \
google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/plugin.pb.h \
google/protobuf/compiler/python/generator.h \ google/protobuf/compiler/python/generator.h \
google/protobuf/compiler/python/pyi_generator.h \ google/protobuf/compiler/python/pyi_generator.h \
google/protobuf/compiler/python/python_generator.h \
google/protobuf/compiler/ruby/ruby_generator.h \ google/protobuf/compiler/ruby/ruby_generator.h \
google/protobuf/descriptor.h \ google/protobuf/descriptor.h \
google/protobuf/descriptor.pb.h \ google/protobuf/descriptor.pb.h \

@ -37,6 +37,7 @@
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h> #include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/cpp/field.h>
#include <google/protobuf/compiler/cpp/helpers.h> #include <google/protobuf/compiler/cpp/helpers.h>
namespace google { namespace google {
@ -55,8 +56,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
(*variables)["default"] = Int32ToString(default_value->number()); (*variables)["default"] = Int32ToString(default_value->number());
(*variables)["full_name"] = descriptor->full_name(); (*variables)["full_name"] = descriptor->full_name();
(*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor);
bool cold = ShouldSplit(descriptor, options);
(*variables)["cached_byte_size_field"] = (*variables)["cached_byte_size_field"] =
MakeVarintCachedSizeFieldName(descriptor); MakeVarintCachedSizeFieldName(descriptor, cold);
} }
} // namespace } // namespace
@ -110,6 +112,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
" $field$ = value;\n" " $field$ = value;\n"
"}\n" "}\n"
"inline void $classname$::set_$name$($type$ value) {\n" "inline void $classname$::set_$name$($type$ value) {\n"
"$maybe_prepare_split_message$"
" _internal_set_$name$(value);\n" " _internal_set_$name$(value);\n"
"$annotate_set$" "$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n" " // @@protoc_insertion_point(field_set:$full_name$)\n"
@ -162,6 +165,10 @@ void EnumFieldGenerator::GenerateConstexprAggregateInitializer(
void EnumFieldGenerator::GenerateAggregateInitializer( void EnumFieldGenerator::GenerateAggregateInitializer(
io::Printer* printer) const { io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
format("decltype(Impl_::Split::$name$_){$default$}");
return;
}
format("decltype($field$){$default$}"); format("decltype($field$){$default$}");
} }

@ -101,7 +101,9 @@ class RepeatedEnumFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override;
void GenerateSwappingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override;
void GenerateConstructorCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override;
void GenerateCopyConstructorCode(io::Printer* printer) const override {} void GenerateCopyConstructorCode(io::Printer* /*printer*/) const override {
GOOGLE_CHECK(!ShouldSplit(descriptor_, options_));
}
void GenerateDestructorCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override;
void GenerateSerializeWithCachedSizesToArray( void GenerateSerializeWithCachedSizesToArray(
io::Printer* printer) const override; io::Printer* printer) const override;

@ -244,7 +244,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["number"] = StrCat(descriptor->number()); (*variables)["number"] = StrCat(descriptor->number());
(*variables)["classname"] = ClassName(FieldScope(descriptor), false); (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
(*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
(*variables)["field"] = FieldMemberName(descriptor); bool split = ShouldSplit(descriptor, options);
(*variables)["field"] = FieldMemberName(descriptor, split);
(*variables)["tag_size"] = StrCat( (*variables)["tag_size"] = StrCat(
WireFormat::TagSize(descriptor->number(), descriptor->type())); WireFormat::TagSize(descriptor->number(), descriptor->type()));
@ -252,6 +253,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["set_hasbit"] = ""; (*variables)["set_hasbit"] = "";
(*variables)["clear_hasbit"] = ""; (*variables)["clear_hasbit"] = "";
(*variables)["maybe_prepare_split_message"] =
split ? " PrepareSplitMessageForWrite();\n" : "";
AddAccessorAnnotations(descriptor, options, variables); AddAccessorAnnotations(descriptor, options, variables);
@ -299,6 +302,10 @@ void FieldGenerator::SetInlinedStringIndex(int32_t inlined_string_index) {
void FieldGenerator::GenerateAggregateInitializer(io::Printer* printer) const { void FieldGenerator::GenerateAggregateInitializer(io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
format("decltype(Impl_::Split::$name$_){arena}");
return;
}
format("decltype($field$){arena}"); format("decltype($field$){arena}");
} }
@ -314,6 +321,15 @@ void FieldGenerator::GenerateCopyAggregateInitializer(
format("decltype($field$){from.$field$}"); format("decltype($field$){from.$field$}");
} }
void FieldGenerator::GenerateCopyConstructorCode(io::Printer* printer) const {
if (ShouldSplit(descriptor_, options_)) {
// There is no copy constructor for the `Split` struct, so we need to copy
// the value here.
Formatter format(printer, variables_);
format("$field$ = from.$field$;\n");
}
}
void SetCommonOneofFieldVariables( void SetCommonOneofFieldVariables(
const FieldDescriptor* descriptor, const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) { std::map<std::string, std::string>* variables) {

@ -136,7 +136,7 @@ class FieldGenerator {
virtual void GenerateMergingCode(io::Printer* printer) const = 0; virtual void GenerateMergingCode(io::Printer* printer) const = 0;
// Generates a copy constructor // Generates a copy constructor
virtual void GenerateCopyConstructorCode(io::Printer* printer) const = 0; virtual void GenerateCopyConstructorCode(io::Printer* printer) const;
// Generate lines of code (statements, not declarations) which swaps // Generate lines of code (statements, not declarations) which swaps
// this field and the corresponding field of another message, which // this field and the corresponding field of another message, which
@ -150,6 +150,9 @@ class FieldGenerator {
// method, invoked by each of the generated constructors. // method, invoked by each of the generated constructors.
virtual void GenerateConstructorCode(io::Printer* printer) const = 0; virtual void GenerateConstructorCode(io::Printer* printer) const = 0;
// Generate initialization code for private members in the cold struct.
virtual void GenerateCreateSplitMessageCode(io::Printer* printer) const {}
// Generate any code that needs to go in the class's SharedDtor() method, // Generate any code that needs to go in the class's SharedDtor() method,
// invoked by the destructor. // invoked by the destructor.
// Most field types don't need this, so the default implementation is empty. // Most field types don't need this, so the default implementation is empty.

@ -480,10 +480,40 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx,
io::Printer* printer) { io::Printer* printer) {
Formatter format(printer, variables_); Formatter format(printer, variables_);
MessageGenerator* generator = message_generators_[idx].get(); MessageGenerator* generator = message_generators_[idx].get();
// Generate the split instance first because it's needed in the constexpr
// constructor.
if (ShouldSplit(generator->descriptor_, options_)) {
// Use a union to disable the destructor of the _instance member.
// We can constant initialize, but the object will still have a non-trivial
// destructor that we need to elide.
format(
"struct $1$ {\n"
" PROTOBUF_CONSTEXPR $1$()\n"
" : _instance{",
DefaultInstanceType(generator->descriptor_, options_,
/*split=*/true));
generator->GenerateInitDefaultSplitInstance(printer);
format(
"} {}\n"
" ~$1$() {}\n"
" union {\n"
" $2$ _instance;\n"
" };\n"
"};\n",
DefaultInstanceType(generator->descriptor_, options_, /*split=*/true),
StrCat(generator->classname_, "::Impl_::Split"));
// NO_DESTROY is not necessary for correctness. The empty destructor is
// enough. However, the empty destructor fails to be elided in some
// configurations (like non-opt or with certain sanitizers). NO_DESTROY is
// there just to improve performance and binary size in these builds.
format(
"PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT "
"PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $1$ $2$;\n",
DefaultInstanceType(generator->descriptor_, options_, /*split=*/true),
DefaultInstanceName(generator->descriptor_, options_, /*split=*/true));
}
generator->GenerateConstexprConstructor(printer); generator->GenerateConstexprConstructor(printer);
// Use a union to disable the destructor of the _instance member.
// We can constant initialize, but the object will still have a non-trivial
// destructor that we need to elide.
format( format(
"struct $1$ {\n" "struct $1$ {\n"
" PROTOBUF_CONSTEXPR $1$()\n" " PROTOBUF_CONSTEXPR $1$()\n"
@ -495,14 +525,11 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx,
"};\n", "};\n",
DefaultInstanceType(generator->descriptor_, options_), DefaultInstanceType(generator->descriptor_, options_),
generator->classname_); generator->classname_);
// NO_DESTROY is not necessary for correctness. The empty destructor is format(
// enough. However, the empty destructor fails to be elided in some "PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT "
// configurations (like non-opt or with certain sanitizers). NO_DESTROY is "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $1$ $2$;\n",
// there just to improve performance and binary size in these builds. DefaultInstanceType(generator->descriptor_, options_),
format("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT " DefaultInstanceName(generator->descriptor_, options_));
"PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $1$ $2$;\n",
DefaultInstanceType(generator->descriptor_, options_),
DefaultInstanceName(generator->descriptor_, options_));
for (int i = 0; i < generator->descriptor_->field_count(); i++) { for (int i = 0; i < generator->descriptor_->field_count(); i++) {
const FieldDescriptor* field = generator->descriptor_->field(i); const FieldDescriptor* field = generator->descriptor_->field(i);
@ -514,7 +541,7 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx,
"($3$._instance.$4$.Init(), std::true_type{});\n", "($3$._instance.$4$.Init(), std::true_type{});\n",
ClassName(generator->descriptor_), FieldName(field), ClassName(generator->descriptor_), FieldName(field),
DefaultInstanceName(generator->descriptor_, options_), DefaultInstanceName(generator->descriptor_, options_),
FieldMemberName(field)); FieldMemberName(field, ShouldSplit(field, options_)));
} }
} }
@ -947,6 +974,7 @@ class FileGenerator::ForwardDeclarations {
public: public:
void AddMessage(const Descriptor* d) { classes_[ClassName(d)] = d; } void AddMessage(const Descriptor* d) { classes_[ClassName(d)] = d; }
void AddEnum(const EnumDescriptor* d) { enums_[ClassName(d)] = d; } void AddEnum(const EnumDescriptor* d) { enums_[ClassName(d)] = d; }
void AddSplit(const Descriptor* d) { splits_[ClassName(d)] = d; }
void Print(const Formatter& format, const Options& options) const { void Print(const Formatter& format, const Options& options) const {
for (const auto& p : enums_) { for (const auto& p : enums_) {
@ -967,6 +995,14 @@ class FileGenerator::ForwardDeclarations {
class_desc, classname, DefaultInstanceType(class_desc, options), class_desc, classname, DefaultInstanceType(class_desc, options),
DefaultInstanceName(class_desc, options)); DefaultInstanceName(class_desc, options));
} }
for (const auto& p : splits_) {
const Descriptor* class_desc = p.second;
format(
"struct $1$;\n"
"$dllexport_decl $extern $1$ $2$;\n",
DefaultInstanceType(class_desc, options, /*split=*/true),
DefaultInstanceName(class_desc, options, /*split=*/true));
}
} }
void PrintTopLevelDecl(const Formatter& format, void PrintTopLevelDecl(const Formatter& format,
@ -982,6 +1018,7 @@ class FileGenerator::ForwardDeclarations {
private: private:
std::map<std::string, const Descriptor*> classes_; std::map<std::string, const Descriptor*> classes_;
std::map<std::string, const EnumDescriptor*> enums_; std::map<std::string, const EnumDescriptor*> enums_;
std::map<std::string, const Descriptor*> splits_;
}; };
static void PublicImportDFS(const FileDescriptor* fd, static void PublicImportDFS(const FileDescriptor* fd,
@ -1027,6 +1064,12 @@ void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
if (d && !public_set.count(d->file())) if (d && !public_set.count(d->file()))
decls[Namespace(d, options_)].AddEnum(d); decls[Namespace(d, options_)].AddEnum(d);
} }
for (const auto& mg : message_generators_) {
const Descriptor* d = mg->descriptor_;
if ((d != nullptr) && (public_set.count(d->file()) == 0u) &&
ShouldSplit(mg->descriptor_, options_))
decls[Namespace(d, options_)].AddSplit(d);
}
{ {
NamespaceOpener ns(format); NamespaceOpener ns(format);

@ -38,6 +38,7 @@
#include <functional> #include <functional>
#include <limits> #include <limits>
#include <map> #include <map>
#include <memory>
#include <queue> #include <queue>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
@ -185,6 +186,80 @@ bool AllocExpected(const Descriptor* descriptor) {
return false; return false;
} }
// Describes different approaches to detect non-canonical int32 encoding. Only
// kNever or kAlways is eligible for *simple* verification methods.
enum class VerifyInt32Type {
kCustom, // Only check if field number matches.
kNever, // Do not check.
kAlways, // Always check.
};
inline VerifySimpleType VerifyInt32TypeToVerifyCustom(VerifyInt32Type t) {
static VerifySimpleType kCustomTypes[] = {
VerifySimpleType::kCustom, VerifySimpleType::kCustomInt32Never,
VerifySimpleType::kCustomInt32Always};
return kCustomTypes[static_cast<int32_t>(t) -
static_cast<int32_t>(VerifyInt32Type::kCustom)];
}
// Returns one of int32 verification types: kNever, kCustom, kAlways.
//
// We need to verify int32 encoding to detect non-canonical encoding (5B for
// negative int32) and fallback to eager parsing.
//
// kNever skips int32 check because there is no int32 field. kAlways
// unconditionally verifies int32 encoding because all or almost varint fields
// are int32. Otherwise, kCustom verifies int32 encoding only on exact field
// number match. Note the following tweaks:
// --uint32 very likely causes false positives. Having one requires kCustom.
// --kCustom may be cheap enough if all int32 fields fit into a bitmask.
// --Otherwise, try always check if X% of varint fields are int32.
VerifyInt32Type ShouldVerifyInt32(const Descriptor* descriptor) {
int num_int32 = 0;
int num_int32_big_number = 0;
int num_uint32 = 0;
int num_other_varint = 0;
for (const auto* field : FieldRange(descriptor)) {
switch (field->type()) {
case FieldDescriptor::TYPE_INT32:
++num_int32;
if (field->number() > 64) ++num_int32_big_number;
break;
case FieldDescriptor::TYPE_UINT32:
++num_uint32;
++num_other_varint;
break;
default:
if (internal::WireFormat::WireTypeForFieldType(field->type()) ==
internal::WireFormatLite::WIRETYPE_VARINT) {
++num_other_varint;
}
break;
}
}
// If there is no int32 fields, no need to check int32 encoding.
if (num_int32 == 0) return VerifyInt32Type::kNever;
// If all varint fields are int32, *always* check int32 encoding.
if (num_other_varint == 0) return VerifyInt32Type::kAlways;
// Negative uint32 encoding will cause fallback eager parsing as it appears
// non-canonical encoding. Also, if all int32 fields fit into a 64 bit mask,
// checking bitmask is affordable. Try exact match in these cases.
if (num_uint32 > 0 || num_int32_big_number == 0) {
return VerifyInt32Type::kCustom;
}
// If a given varint is likely int32, we should just always check. Let's use
// an arbitrary threshold of 75% (#int32 / #varints).
constexpr int kLikelyInt32Pct = 75;
return (100 * num_int32) / (num_int32 + num_other_varint) >= kLikelyInt32Pct
? VerifyInt32Type::kAlways
: VerifyInt32Type::kCustom;
}
} // namespace } // namespace
bool IsLazy(const FieldDescriptor* field, const Options& options, bool IsLazy(const FieldDescriptor* field, const Options& options,
@ -261,6 +336,8 @@ void SetCommonMessageDataVariables(
(*variables)["oneof_case"] = prefix + "_oneof_case_"; (*variables)["oneof_case"] = prefix + "_oneof_case_";
(*variables)["tracker"] = "Impl_::_tracker_"; (*variables)["tracker"] = "Impl_::_tracker_";
(*variables)["weak_field_map"] = prefix + "_weak_field_map_"; (*variables)["weak_field_map"] = prefix + "_weak_field_map_";
(*variables)["split"] = prefix + "_split_";
(*variables)["cached_split_ptr"] = "cached_split_ptr";
} }
void SetUnknownFieldsVariable(const Descriptor* descriptor, void SetUnknownFieldsVariable(const Descriptor* descriptor,
@ -425,29 +502,32 @@ std::string Namespace(const EnumDescriptor* d, const Options& options) {
} }
std::string DefaultInstanceType(const Descriptor* descriptor, std::string DefaultInstanceType(const Descriptor* descriptor,
const Options& options) { const Options& /*options*/, bool split) {
return ClassName(descriptor) + "DefaultTypeInternal"; return ClassName(descriptor) + (split ? "__Impl_Split" : "") +
"DefaultTypeInternal";
} }
std::string DefaultInstanceName(const Descriptor* descriptor, std::string DefaultInstanceName(const Descriptor* descriptor,
const Options& options) { const Options& /*options*/, bool split) {
return "_" + ClassName(descriptor, false) + "_default_instance_"; return "_" + ClassName(descriptor, false) + (split ? "__Impl_Split" : "") +
"_default_instance_";
} }
std::string DefaultInstancePtr(const Descriptor* descriptor, std::string DefaultInstancePtr(const Descriptor* descriptor,
const Options& options) { const Options& options, bool split) {
return DefaultInstanceName(descriptor, options) + "ptr_"; return DefaultInstanceName(descriptor, options, split) + "ptr_";
} }
std::string QualifiedDefaultInstanceName(const Descriptor* descriptor, std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
const Options& options) { const Options& options, bool split) {
return QualifiedFileLevelSymbol( return QualifiedFileLevelSymbol(
descriptor->file(), DefaultInstanceName(descriptor, options), options); descriptor->file(), DefaultInstanceName(descriptor, options, split),
options);
} }
std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor, std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
const Options& options) { const Options& options, bool split) {
return QualifiedDefaultInstanceName(descriptor, options) + "ptr_"; return QualifiedDefaultInstanceName(descriptor, options, split) + "ptr_";
} }
std::string DescriptorTableName(const FileDescriptor* file, std::string DescriptorTableName(const FileDescriptor* file,
@ -487,12 +567,15 @@ std::string FieldName(const FieldDescriptor* field) {
return result; return result;
} }
std::string FieldMemberName(const FieldDescriptor* field) { std::string FieldMemberName(const FieldDescriptor* field, bool split) {
StringPiece prefix = StringPiece prefix =
IsMapEntryMessage(field->containing_type()) ? "" : "_impl_."; IsMapEntryMessage(field->containing_type()) ? "" : "_impl_.";
StringPiece split_prefix = split ? "_split_->" : "";
if (field->real_containing_oneof() == nullptr) { if (field->real_containing_oneof() == nullptr) {
return StrCat(prefix, FieldName(field), "_"); return StrCat(prefix, split_prefix, FieldName(field), "_");
} }
// Oneof fields are enver split.
GOOGLE_CHECK(!split);
return StrCat(prefix, field->containing_oneof()->name(), "_.", return StrCat(prefix, field->containing_oneof()->name(), "_.",
FieldName(field), "_"); FieldName(field), "_");
} }
@ -875,6 +958,9 @@ bool HasLazyFields(const FileDescriptor* file, const Options& options,
return false; return false;
} }
bool ShouldSplit(const Descriptor*, const Options&) { return false; }
bool ShouldSplit(const FieldDescriptor*, const Options&) { return false; }
static bool HasRepeatedFields(const Descriptor* descriptor) { static bool HasRepeatedFields(const Descriptor* descriptor) {
for (int i = 0; i < descriptor->field_count(); ++i) { for (int i = 0; i < descriptor->field_count(); ++i) {
if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) { if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) {
@ -1016,9 +1102,9 @@ bool IsUtf8String(const FieldDescriptor* field) {
field->type() == FieldDescriptor::TYPE_STRING; field->type() == FieldDescriptor::TYPE_STRING;
} }
bool ShouldVerifySimple(const Descriptor* descriptor) { VerifySimpleType ShouldVerifySimple(const Descriptor* descriptor) {
(void)descriptor; (void)descriptor;
return false; return VerifySimpleType::kCustom;
} }
bool IsStringOrMessage(const FieldDescriptor* field) { bool IsStringOrMessage(const FieldDescriptor* field) {

@ -153,24 +153,26 @@ std::string QualifiedExtensionName(const FieldDescriptor* d);
// Type name of default instance. // Type name of default instance.
std::string DefaultInstanceType(const Descriptor* descriptor, std::string DefaultInstanceType(const Descriptor* descriptor,
const Options& options); const Options& options, bool split = false);
// Non-qualified name of the default_instance of this message. // Non-qualified name of the default_instance of this message.
std::string DefaultInstanceName(const Descriptor* descriptor, std::string DefaultInstanceName(const Descriptor* descriptor,
const Options& options); const Options& options, bool split = false);
// Non-qualified name of the default instance pointer. This is used only for // Non-qualified name of the default instance pointer. This is used only for
// implicit weak fields, where we need an extra indirection. // implicit weak fields, where we need an extra indirection.
std::string DefaultInstancePtr(const Descriptor* descriptor, std::string DefaultInstancePtr(const Descriptor* descriptor,
const Options& options); const Options& options, bool split = false);
// Fully qualified name of the default_instance of this message. // Fully qualified name of the default_instance of this message.
std::string QualifiedDefaultInstanceName(const Descriptor* descriptor, std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
const Options& options); const Options& options,
bool split = false);
// Fully qualified name of the default instance pointer. // Fully qualified name of the default instance pointer.
std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor, std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
const Options& options); const Options& options,
bool split = false);
// DescriptorTable variable name. // DescriptorTable variable name.
std::string DescriptorTableName(const FileDescriptor* file, std::string DescriptorTableName(const FileDescriptor* file,
@ -194,7 +196,7 @@ std::string ResolveKeyword(const std::string& name);
std::string FieldName(const FieldDescriptor* field); std::string FieldName(const FieldDescriptor* field);
// Returns the (unqualified) private member name for this field in C++ code. // Returns the (unqualified) private member name for this field in C++ code.
std::string FieldMemberName(const FieldDescriptor* field); std::string FieldMemberName(const FieldDescriptor* field, bool split);
// Returns an estimate of the compiler's alignment for the field. This // Returns an estimate of the compiler's alignment for the field. This
// can't guarantee to be correct because the generated code could be compiled on // can't guarantee to be correct because the generated code could be compiled on
@ -369,6 +371,12 @@ bool IsEagerlyVerifiedLazy(const FieldDescriptor* field, const Options& options,
bool IsLazilyVerifiedLazy(const FieldDescriptor* field, const Options& options); bool IsLazilyVerifiedLazy(const FieldDescriptor* field, const Options& options);
// Is the given message being split (go/pdsplit)?
bool ShouldSplit(const Descriptor* desc, const Options& options);
// Is the given field being split out?
bool ShouldSplit(const FieldDescriptor* field, const Options& options);
inline bool IsFieldUsed(const FieldDescriptor* /* field */, inline bool IsFieldUsed(const FieldDescriptor* /* field */,
const Options& /* options */) { const Options& /* options */) {
return true; return true;
@ -508,8 +516,10 @@ inline std::string MakeVarintCachedSizeName(const FieldDescriptor* field) {
// MakeVarintCachedSizeFieldName, in case the field exists at some nested level // MakeVarintCachedSizeFieldName, in case the field exists at some nested level
// like: // like:
// internal_container_._field_cached_byte_size_; // internal_container_._field_cached_byte_size_;
inline std::string MakeVarintCachedSizeFieldName(const FieldDescriptor* field) { inline std::string MakeVarintCachedSizeFieldName(const FieldDescriptor* field,
return StrCat("_impl_._", FieldName(field), "_cached_byte_size_"); bool split) {
return StrCat("_impl_.", split ? "_split_->" : "", "_",
FieldName(field), "_cached_byte_size_");
} }
// Note: A lot of libraries detect Any protos based on Descriptor::full_name() // Note: A lot of libraries detect Any protos based on Descriptor::full_name()
@ -1021,7 +1031,24 @@ bool ShouldVerify(const Descriptor* descriptor, const Options& options,
bool ShouldVerify(const FileDescriptor* file, const Options& options, bool ShouldVerify(const FileDescriptor* file, const Options& options,
MessageSCCAnalyzer* scc_analyzer); MessageSCCAnalyzer* scc_analyzer);
bool ShouldVerifySimple(const Descriptor* descriptor); // Indicates whether to use predefined verify methods for a given message. If a
// message is "simple" and needs no special verification per field (e.g. message
// field, repeated packed, UTF8 string, etc.), we can use either VerifySimple or
// VerifySimpleAlwaysCheckInt32 methods as all verification can be done based on
// the wire type.
//
// Otherwise, we need "custom" verify methods tailored to a message to pass
// which field needs a special verification; i.e. InternalVerify.
enum class VerifySimpleType {
kSimpleInt32Never, // Use VerifySimple
kSimpleInt32Always, // Use VerifySimpleAlwaysCheckInt32
kCustom, // Use InternalVerify and check only for int32
kCustomInt32Never, // Use InternalVerify but never check for int32
kCustomInt32Always, // Use InternalVerify and always check for int32
};
// Returns VerifySimpleType if messages can be verified by predefined methods.
VerifySimpleType ShouldVerifySimple(const Descriptor* descriptor);
bool IsUtf8String(const FieldDescriptor* field); bool IsUtf8String(const FieldDescriptor* field);

@ -136,6 +136,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n" "}\n"
"inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n" "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
"$classname$::_internal_mutable_$name$() {\n" "$classname$::_internal_mutable_$name$() {\n"
"$maybe_prepare_split_message$"
" return $field$.MutableMap();\n" " return $field$.MutableMap();\n"
"}\n" "}\n"
"inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n" "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
@ -291,6 +292,12 @@ void MapFieldGenerator::GenerateCopyAggregateInitializer(
void MapFieldGenerator::GenerateAggregateInitializer( void MapFieldGenerator::GenerateAggregateInitializer(
io::Printer* printer) const { io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
format(
"/*decltype($classname$::Split::$name$_)*/"
"{::_pbi::ArenaInitialized(), arena}");
return;
}
// MapField has no move constructor. // MapField has no move constructor.
format("/*decltype($field$)*/{::_pbi::ArenaInitialized(), arena}"); format("/*decltype($field$)*/{::_pbi::ArenaInitialized(), arena}");
} }
@ -299,6 +306,11 @@ void MapFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
format("$cached_split_ptr$->$name$_.Destruct();\n");
format("$cached_split_ptr$->$name$_.~MapField$lite$();\n");
return;
}
format("$field$.Destruct();\n"); format("$field$.Destruct();\n");
format("$field$.~MapField$lite$();\n"); format("$field$.~MapField$lite$();\n");
} }

@ -346,10 +346,10 @@ bool IsRequired(const std::vector<const FieldDescriptor*>& v) {
return v.front()->is_required(); return v.front()->is_required();
} }
bool HasSingularString(const Descriptor* desc, const Options& options) { bool HasNonSplitOptionalString(const Descriptor* desc, const Options& options) {
for (const auto* field : FieldRange(desc)) { for (const auto* field : FieldRange(desc)) {
if (IsString(field, options) && !field->is_repeated() && if (IsString(field, options) && !field->is_repeated() &&
!field->real_containing_oneof()) { !field->real_containing_oneof() && !ShouldSplit(field, options)) {
return true; return true;
} }
} }
@ -1202,6 +1202,9 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
format.Outdent(); format.Outdent();
format("}\n"); format("}\n");
} else { } else {
if (ShouldSplit(field, options_)) {
format("if (IsSplitMessageDefault()) return;\n");
}
field_generators_.get(field).GenerateClearingCode(format.printer()); field_generators_.get(field).GenerateClearingCode(format.printer());
if (HasHasbit(field)) { if (HasHasbit(field)) {
int has_bit_index = HasBitIndex(field); int has_bit_index = HasBitIndex(field);
@ -1242,13 +1245,12 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
} else { } else {
format( format(
"inline int $classname$::_internal_$name$_size() const {\n" "inline int $classname$::_internal_$name$_size() const {\n"
" return $1$$2$.size();\n" " return $field$$1$.size();\n"
"}\n" "}\n"
"inline int $classname$::$name$_size() const {\n" "inline int $classname$::$name$_size() const {\n"
"$annotate_size$" "$annotate_size$"
" return _internal_$name$_size();\n" " return _internal_$name$_size();\n"
"}\n", "}\n",
FieldMemberName(field),
IsImplicitWeakField(field, options_, scc_analyzer_) && IsImplicitWeakField(field, options_, scc_analyzer_) &&
field->message_type() field->message_type()
? ".weak" ? ".weak"
@ -1752,6 +1754,17 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"\n"); "\n");
} }
if (ShouldSplit(descriptor_, options_)) {
format(
"private:\n"
"inline bool IsSplitMessageDefault() const {\n"
" return $split$ == reinterpret_cast<Impl_::Split*>(&$1$);\n"
"}\n"
"PROTOBUF_NOINLINE void PrepareSplitMessageForWrite();\n"
"public:\n",
DefaultInstanceName(descriptor_, options_, /*split=*/true));
}
format( format(
"// nested types ----------------------------------------------------\n" "// nested types ----------------------------------------------------\n"
"\n"); "\n");
@ -1896,7 +1909,24 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
for (auto field : optimized_order_) { for (auto field : optimized_order_) {
const FieldGenerator& generator = field_generators_.get(field); const FieldGenerator& generator = field_generators_.get(field);
generator.GenerateStaticMembers(printer); generator.GenerateStaticMembers(printer);
generator.GeneratePrivateMembers(printer); if (!ShouldSplit(field, options_)) {
generator.GeneratePrivateMembers(printer);
}
}
if (ShouldSplit(descriptor_, options_)) {
format("struct Split {\n");
format.Indent();
for (auto field : optimized_order_) {
if (!ShouldSplit(field, options_)) continue;
const FieldGenerator& generator = field_generators_.get(field);
generator.GeneratePrivateMembers(printer);
}
format.Outdent();
format(
" typedef void InternalArenaConstructable_;\n"
" typedef void DestructorSkippable_;\n"
"};\n"
"Split* _split_;\n");
} }
// For each oneof generate a union // For each oneof generate a union
@ -1955,6 +1985,14 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
format("union { Impl_ _impl_; };\n"); format("union { Impl_ _impl_; };\n");
} }
if (ShouldSplit(descriptor_, options_)) {
format(
"static Impl_::Split* CreateSplitMessage("
"::$proto_ns$::Arena* arena);\n");
format("friend struct $1$;\n",
DefaultInstanceType(descriptor_, options_, /*split=*/true));
}
// The TableStruct struct needs access to the private parts, in order to // The TableStruct struct needs access to the private parts, in order to
// construct the offsets of all members. // construct the offsets of all members.
format("friend struct ::$tablename$;\n"); format("friend struct ::$tablename$;\n");
@ -2094,7 +2132,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
format("};\n\n"); format("};\n\n");
for (auto field : FieldRange(descriptor_)) { for (auto field : FieldRange(descriptor_)) {
if (!IsFieldStripped(field, options_)) { if (!IsFieldStripped(field, options_)) {
field_generators_.get(field).GenerateInternalAccessorDefinitions(printer); field_generators_.get(field).GenerateInternalAccessorDefinitions(
printer);
} }
} }
@ -2154,6 +2193,15 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
format("\n"); format("\n");
} }
if (ShouldSplit(descriptor_, options_)) {
format(
"void $classname$::PrepareSplitMessageForWrite() {\n"
" if (IsSplitMessageDefault()) {\n"
" $split$ = CreateSplitMessage(GetArenaForAllocation());\n"
" }\n"
"}\n");
}
GenerateVerify(printer); GenerateVerify(printer);
GenerateSwap(printer); GenerateSwap(printer);
@ -2242,7 +2290,11 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
// Don't use the top bit because that is for unused fields. // Don't use the top bit because that is for unused fields.
format("::_pbi::kInvalidFieldOffsetTag"); format("::_pbi::kInvalidFieldOffsetTag");
} else { } else {
format("PROTOBUF_FIELD_OFFSET($classtype$, $1$)", FieldMemberName(field)); format("PROTOBUF_FIELD_OFFSET($classtype$$1$, $2$)",
ShouldSplit(field, options_) ? "::Impl_::Split" : "",
ShouldSplit(field, options_)
? FieldName(field) + "_"
: FieldMemberName(field, /*cold=*/false));
} }
// Some information about a field is in the pdproto profile. The profile is // Some information about a field is in the pdproto profile. The profile is
@ -2338,9 +2390,17 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
// Initialize member variables with arena constructor. // Initialize member variables with arena constructor.
for (auto field : optimized_order_) { for (auto field : optimized_order_) {
GOOGLE_DCHECK(!IsFieldStripped(field, options_)); GOOGLE_DCHECK(!IsFieldStripped(field, options_));
if (ShouldSplit(field, options_)) {
continue;
}
put_sep(); put_sep();
field_generators_.get(field).GenerateAggregateInitializer(printer); field_generators_.get(field).GenerateAggregateInitializer(printer);
} }
if (ShouldSplit(descriptor_, options_)) {
put_sep();
format("decltype($split$){reinterpret_cast<Impl_::Split*>(&$1$)}",
DefaultInstanceName(descriptor_, options_, /*split=*/true));
}
for (auto oneof : OneOfRange(descriptor_)) { for (auto oneof : OneOfRange(descriptor_)) {
put_sep(); put_sep();
format("decltype(_impl_.$1$_){}", oneof->name()); format("decltype(_impl_.$1$_){}", oneof->name());
@ -2394,6 +2454,9 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
} }
for (const FieldDescriptor* field : optimized_order_) { for (const FieldDescriptor* field : optimized_order_) {
if (ShouldSplit(field, options_)) {
continue;
}
field_generators_.get(field).GenerateConstructorCode(printer); field_generators_.get(field).GenerateConstructorCode(printer);
} }
@ -2405,6 +2468,63 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
format("}\n\n"); format("}\n\n");
} }
void MessageGenerator::GenerateCreateSplitMessage(io::Printer* printer) {
Formatter format(printer, variables_);
format(
"$classname$::Impl_::Split* "
"$classname$::CreateSplitMessage(::$proto_ns$::Arena* arena) {\n");
format.Indent();
const char* field_sep = " ";
const auto put_sep = [&] {
format("\n$1$ ", field_sep);
field_sep = ",";
};
format(
"const size_t size = sizeof(Impl_::Split);\n"
"void* chunk = (arena == nullptr) ?\n"
" ::operator new(size) :\n"
" arena->AllocateAligned(size, alignof(Impl_::Split));\n"
"Impl_::Split* ptr = reinterpret_cast<Impl_::Split*>(chunk);\n"
"new (ptr) Impl_::Split{");
format.Indent();
for (const FieldDescriptor* field : optimized_order_) {
GOOGLE_DCHECK(!IsFieldStripped(field, options_));
if (ShouldSplit(field, options_)) {
put_sep();
field_generators_.get(field).GenerateAggregateInitializer(printer);
}
}
format.Outdent();
format("};\n");
for (const FieldDescriptor* field : optimized_order_) {
GOOGLE_DCHECK(!IsFieldStripped(field, options_));
if (ShouldSplit(field, options_)) {
field_generators_.get(field).GenerateCreateSplitMessageCode(printer);
}
}
format("return ptr;\n");
format.Outdent();
format("}\n");
}
void MessageGenerator::GenerateInitDefaultSplitInstance(io::Printer* printer) {
if (!ShouldSplit(descriptor_, options_)) return;
Formatter format(printer, variables_);
const char* field_sep = " ";
const auto put_sep = [&] {
format("\n$1$ ", field_sep);
field_sep = ",";
};
for (const auto* field : optimized_order_) {
if (ShouldSplit(field, options_)) {
put_sep();
field_generators_.get(field).GenerateConstexprAggregateInitializer(
printer);
}
}
}
void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
if (HasSimpleBaseClass(descriptor_, options_)) return; if (HasSimpleBaseClass(descriptor_, options_)) return;
Formatter format(printer, variables_); Formatter format(printer, variables_);
@ -2420,8 +2540,24 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
// Write the destructors for each field except oneof members. // Write the destructors for each field except oneof members.
// optimized_order_ does not contain oneof fields. // optimized_order_ does not contain oneof fields.
for (auto field : optimized_order_) { for (auto field : optimized_order_) {
if (ShouldSplit(field, options_)) {
continue;
}
field_generators_.get(field).GenerateDestructorCode(printer); field_generators_.get(field).GenerateDestructorCode(printer);
} }
if (ShouldSplit(descriptor_, options_)) {
format("if (!IsSplitMessageDefault()) {\n");
format.Indent();
format("auto* $cached_split_ptr$ = $split$;\n");
for (auto field : optimized_order_) {
if (ShouldSplit(field, options_)) {
field_generators_.get(field).GenerateDestructorCode(printer);
}
}
format("delete $cached_split_ptr$;\n");
format.Outdent();
format("}\n");
}
// Generate code to destruct oneofs. Clearing should do the work. // Generate code to destruct oneofs. Clearing should do the work.
for (auto oneof : OneOfRange(descriptor_)) { for (auto oneof : OneOfRange(descriptor_)) {
@ -2475,10 +2611,23 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) {
// Process non-oneof fields first. // Process non-oneof fields first.
for (auto field : optimized_order_) { for (auto field : optimized_order_) {
if (IsFieldStripped(field, options_)) continue; if (IsFieldStripped(field, options_) || ShouldSplit(field, options_))
continue;
const FieldGenerator& fg = field_generators_.get(field); const FieldGenerator& fg = field_generators_.get(field);
fg.GenerateArenaDestructorCode(printer); fg.GenerateArenaDestructorCode(printer);
} }
if (ShouldSplit(descriptor_, options_)) {
format("if (!_this->IsSplitMessageDefault()) {\n");
format.Indent();
for (auto field : optimized_order_) {
if (IsFieldStripped(field, options_) || !ShouldSplit(field, options_))
continue;
const FieldGenerator& fg = field_generators_.get(field);
fg.GenerateArenaDestructorCode(printer);
}
format.Outdent();
format("}\n");
}
// Process oneof fields. // Process oneof fields.
for (auto oneof : OneOfRange(descriptor_)) { for (auto oneof : OneOfRange(descriptor_)) {
@ -2532,9 +2681,19 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* printer) {
} }
} }
for (auto field : optimized_order_) { for (auto field : optimized_order_) {
if (ShouldSplit(field, options_)) {
continue;
}
put_sep();
field_generators_.get(field).GenerateConstexprAggregateInitializer(
printer);
}
if (ShouldSplit(descriptor_, options_)) {
put_sep(); put_sep();
field_generators_.get(field).GenerateConstexprAggregateInitializer(printer); format("/*decltype($split$)*/&$1$._instance",
DefaultInstanceName(descriptor_, options_, /*split=*/true));
} }
for (auto oneof : OneOfRange(descriptor_)) { for (auto oneof : OneOfRange(descriptor_)) {
put_sep(); put_sep();
format("/*decltype(_impl_.$1$_)*/{}", oneof->name()); format("/*decltype(_impl_.$1$_)*/{}", oneof->name());
@ -2570,16 +2729,33 @@ void MessageGenerator::GenerateCopyConstructorBody(io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
const RunMap runs = const RunMap runs =
FindRuns(optimized_order_, FindRuns(optimized_order_, [this](const FieldDescriptor* field) {
[](const FieldDescriptor* field) { return IsPOD(field); }); return IsPOD(field) && !ShouldSplit(field, options_);
});
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 (ShouldSplit(descriptor_, options_)) {
format("if (!from.IsSplitMessageDefault()) {\n");
format.Indent();
format("_this->PrepareSplitMessageForWrite();\n");
for (auto field : optimized_order_) {
if (ShouldSplit(field, options_)) {
field_generators_.get(field).GenerateCopyConstructorCode(printer);
}
}
format.Outdent();
format("}\n");
}
for (size_t i = 0; i < optimized_order_.size(); ++i) { for (size_t i = 0; i < optimized_order_.size(); ++i) {
const FieldDescriptor* field = optimized_order_[i]; const FieldDescriptor* field = optimized_order_[i];
if (ShouldSplit(field, options_)) {
continue;
}
const auto it = runs.find(field); const auto it = runs.find(field);
// We only apply the memset technique to runs of more than one field, as // We only apply the memset technique to runs of more than one field, as
@ -2587,9 +2763,10 @@ void MessageGenerator::GenerateCopyConstructorBody(io::Printer* printer) const {
if (it != runs.end() && it->second > 1) { if (it != runs.end() && it->second > 1) {
// Use a memset, then skip run_length fields. // Use a memset, then skip run_length fields.
const size_t run_length = it->second; const size_t run_length = it->second;
const std::string first_field_name = FieldMemberName(field); const std::string first_field_name =
FieldMemberName(field, /*cold=*/false);
const std::string last_field_name = const std::string last_field_name =
FieldMemberName(optimized_order_[i + run_length - 1]); FieldMemberName(optimized_order_[i + run_length - 1], /*cold=*/false);
format.Set("first", first_field_name); format.Set("first", first_field_name);
format.Set("last", last_field_name); format.Set("last", last_field_name);
@ -2682,9 +2859,17 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
// Initialize member variables with arena constructor. // Initialize member variables with arena constructor.
for (auto field : optimized_order_) { for (auto field : optimized_order_) {
if (ShouldSplit(field, options_)) {
continue;
}
put_sep(); put_sep();
field_generators_.get(field).GenerateCopyAggregateInitializer(printer); field_generators_.get(field).GenerateCopyAggregateInitializer(printer);
} }
if (ShouldSplit(descriptor_, options_)) {
put_sep();
format("decltype($split$){reinterpret_cast<Impl_::Split*>(&$1$)}",
DefaultInstanceName(descriptor_, options_, /*split=*/true));
}
for (auto oneof : OneOfRange(descriptor_)) { for (auto oneof : OneOfRange(descriptor_)) {
put_sep(); put_sep();
format("decltype(_impl_.$1$_){}", oneof->name()); format("decltype(_impl_.$1$_){}", oneof->name());
@ -2760,6 +2945,10 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
// Generate the shared constructor code. // Generate the shared constructor code.
GenerateSharedConstructorCode(printer); GenerateSharedConstructorCode(printer);
if (ShouldSplit(descriptor_, options_)) {
GenerateCreateSplitMessage(printer);
}
// Generate the destructor. // Generate the destructor.
if (!HasSimpleBaseClass(descriptor_, options_)) { if (!HasSimpleBaseClass(descriptor_, options_)) {
format( format(
@ -2857,6 +3046,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
// (memset) per chunk, and if present it will be at the beginning. // (memset) per chunk, and if present it will be at the beginning.
bool same = HasByteIndex(a) == HasByteIndex(b) && bool same = HasByteIndex(a) == HasByteIndex(b) &&
a->is_repeated() == b->is_repeated() && a->is_repeated() == b->is_repeated() &&
ShouldSplit(a, options_) == ShouldSplit(b, options_) &&
(CanInitializeByZeroing(a) == CanInitializeByZeroing(b) || (CanInitializeByZeroing(a) == CanInitializeByZeroing(b) ||
(CanInitializeByZeroing(a) && (CanInitializeByZeroing(a) &&
(chunk_count == 1 || merge_zero_init))); (chunk_count == 1 || merge_zero_init)));
@ -2875,7 +3065,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
const FieldDescriptor* memset_start = nullptr; const FieldDescriptor* memset_start = nullptr;
const FieldDescriptor* memset_end = nullptr; const FieldDescriptor* memset_end = nullptr;
bool saw_non_zero_init = false; bool saw_non_zero_init = false;
bool chunk_is_cold = !chunk.empty() && ShouldSplit(chunk.front(), options_);
for (const auto& field : chunk) { for (const auto& field : chunk) {
if (CanInitializeByZeroing(field)) { if (CanInitializeByZeroing(field)) {
GOOGLE_CHECK(!saw_non_zero_init); GOOGLE_CHECK(!saw_non_zero_init);
@ -2915,17 +3105,25 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
format.Indent(); format.Indent();
} }
if (chunk_is_cold) {
format("if (!IsSplitMessageDefault()) {\n");
format.Indent();
}
if (memset_start) { if (memset_start) {
if (memset_start == memset_end) { if (memset_start == memset_end) {
// For clarity, do not memset a single field. // For clarity, do not memset a single field.
field_generators_.get(memset_start) field_generators_.get(memset_start)
.GenerateMessageClearingCode(printer); .GenerateMessageClearingCode(printer);
} else { } else {
GOOGLE_CHECK_EQ(chunk_is_cold, ShouldSplit(memset_start, options_));
GOOGLE_CHECK_EQ(chunk_is_cold, 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), FieldMemberName(memset_end)); FieldMemberName(memset_start, chunk_is_cold),
FieldMemberName(memset_end, chunk_is_cold));
} }
} }
@ -2954,6 +3152,11 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
} }
} }
if (chunk_is_cold) {
format.Outdent();
format("}\n");
}
if (have_outer_if) { if (have_outer_if) {
format.Outdent(); format.Outdent();
format("}\n"); format("}\n");
@ -3052,7 +3255,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
SetUnknownFieldsVariable(descriptor_, options_, &vars); SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars); format.AddMap(vars);
if (HasSingularString(descriptor_, options_)) { if (HasNonSplitOptionalString(descriptor_, options_)) {
format( format(
"auto* lhs_arena = GetArenaForAllocation();\n" "auto* lhs_arena = GetArenaForAllocation();\n"
"auto* rhs_arena = other->GetArenaForAllocation();\n"); "auto* rhs_arena = other->GetArenaForAllocation();\n");
@ -3068,11 +3271,15 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
// If possible, we swap several fields at once, including padding. // If possible, we swap several fields at once, including padding.
const RunMap runs = const RunMap runs =
FindRuns(optimized_order_, [this](const FieldDescriptor* field) { FindRuns(optimized_order_, [this](const FieldDescriptor* field) {
return CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_); return !ShouldSplit(field, options_) &&
CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_);
}); });
for (int i = 0; i < optimized_order_.size(); ++i) { for (size_t i = 0; i < optimized_order_.size(); ++i) {
const FieldDescriptor* field = optimized_order_[i]; const FieldDescriptor* field = optimized_order_[i];
if (ShouldSplit(field, options_)) {
continue;
}
const auto it = runs.find(field); const auto it = runs.find(field);
// We only apply the memswap technique to runs of more than one field, as // We only apply the memswap technique to runs of more than one field, as
@ -3081,9 +3288,10 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
if (it != runs.end() && it->second > 1) { if (it != runs.end() && it->second > 1) {
// Use a memswap, then skip run_length fields. // Use a memswap, then skip run_length fields.
const size_t run_length = it->second; const size_t run_length = it->second;
const std::string first_field_name = FieldMemberName(field); const std::string first_field_name =
const std::string last_field_name = FieldMemberName(field, /*cold=*/false);
FieldMemberName(optimized_order_[i + run_length - 1]); const std::string last_field_name = FieldMemberName(
optimized_order_[i + run_length - 1], /*cold=*/false);
format.Set("first", first_field_name); format.Set("first", first_field_name);
format.Set("last", last_field_name); format.Set("last", last_field_name);
@ -3102,6 +3310,9 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
field_generators_.get(field).GenerateSwappingCode(printer); field_generators_.get(field).GenerateSwappingCode(printer);
} }
} }
if (ShouldSplit(descriptor_, options_)) {
format("swap($split$, other->$split$);\n");
}
for (auto oneof : OneOfRange(descriptor_)) { for (auto oneof : OneOfRange(descriptor_)) {
format("swap(_impl_.$1$_, other->_impl_.$1$_);\n", oneof->name()); format("swap(_impl_.$1$_, other->_impl_.$1$_);\n", oneof->name());
@ -3208,10 +3419,18 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* printer) {
"$uint32$ cached_has_bits = 0;\n" "$uint32$ cached_has_bits = 0;\n"
"(void) cached_has_bits;\n\n"); "(void) cached_has_bits;\n\n");
if (ShouldSplit(descriptor_, options_)) {
format(
"if (!from.IsSplitMessageDefault()) {\n"
" _this->PrepareSplitMessageForWrite();\n"
"}\n");
}
std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields( std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
optimized_order_, optimized_order_,
[&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool { [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
return HasByteIndex(a) == HasByteIndex(b); return HasByteIndex(a) == HasByteIndex(b) &&
ShouldSplit(a, options_) == ShouldSplit(b, options_);
}); });
ColdChunkSkipper cold_skipper(descriptor_, options_, chunks, has_bit_indices_, ColdChunkSkipper cold_skipper(descriptor_, options_, chunks, has_bit_indices_,
@ -3999,7 +4218,8 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields( std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
optimized_order_, optimized_order_,
[&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool { [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b); return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b) &&
ShouldSplit(a, options_) == ShouldSplit(b, options_);
}); });
// Remove chunks with required fields. // Remove chunks with required fields.

@ -119,6 +119,9 @@ class MessageGenerator {
// default instance. // default instance.
void GenerateConstexprConstructor(io::Printer* printer); void GenerateConstexprConstructor(io::Printer* printer);
void GenerateCreateSplitMessage(io::Printer* printer);
void GenerateInitDefaultSplitInstance(io::Printer* printer);
// Generate standard Message methods. // Generate standard Message methods.
void GenerateClear(io::Printer* printer); void GenerateClear(io::Printer* printer);
void GenerateOneofClear(io::Printer* printer); void GenerateOneofClear(io::Printer* printer);

@ -35,6 +35,7 @@
#include <google/protobuf/compiler/cpp/message_field.h> #include <google/protobuf/compiler/cpp/message_field.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.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/stubs/strutil.h> #include <google/protobuf/stubs/strutil.h>
@ -178,6 +179,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
format( format(
"inline void $classname$::unsafe_arena_set_allocated_$name$(\n" "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
" $type$* $name$) {\n" " $type$* $name$) {\n"
"$maybe_prepare_split_message$"
// If we're not on an arena, free whatever we were holding before. // If we're not on an arena, free whatever we were holding before.
// (If we are on arena, we can just forget the earlier pointer.) // (If we are on arena, we can just forget the earlier pointer.)
" if (GetArenaForAllocation() == nullptr) {\n" " if (GetArenaForAllocation() == nullptr) {\n"
@ -203,6 +205,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
"inline $type$* $classname$::$release_name$() {\n" "inline $type$* $classname$::$release_name$() {\n"
"$type_reference_function$" "$type_reference_function$"
"$annotate_release$" "$annotate_release$"
"$maybe_prepare_split_message$"
" $clear_hasbit$\n" " $clear_hasbit$\n"
" $type$* temp = $casted_member$;\n" " $type$* temp = $casted_member$;\n"
" $field$ = nullptr;\n" " $field$ = nullptr;\n"
@ -221,6 +224,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
"$annotate_release$" "$annotate_release$"
" // @@protoc_insertion_point(field_release:$full_name$)\n" " // @@protoc_insertion_point(field_release:$full_name$)\n"
"$type_reference_function$" "$type_reference_function$"
"$maybe_prepare_split_message$"
" $clear_hasbit$\n" " $clear_hasbit$\n"
" $type$* temp = $casted_member$;\n" " $type$* temp = $casted_member$;\n"
" $field$ = nullptr;\n" " $field$ = nullptr;\n"
@ -243,6 +247,9 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
" return $casted_member$;\n" " return $casted_member$;\n"
"}\n" "}\n"
"inline $type$* $classname$::mutable_$name$() {\n" "inline $type$* $classname$::mutable_$name$() {\n"
// TODO(b/122856539): add tests to make sure all write accessors are able
// to prepare split message allocation.
"$maybe_prepare_split_message$"
" $type$* _msg = _internal_mutable_$name$();\n" " $type$* _msg = _internal_mutable_$name$();\n"
"$annotate_mutable$" "$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
@ -254,7 +261,9 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
format( format(
"inline void $classname$::set_allocated_$name$($type$* $name$) {\n" "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
" ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n"); " ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n");
format(" if (message_arena == nullptr) {\n"); format(
"$maybe_prepare_split_message$"
" if (message_arena == nullptr) {\n");
if (IsCrossFileMessage(descriptor_)) { if (IsCrossFileMessage(descriptor_)) {
format( format(
" delete reinterpret_cast< ::$proto_ns$::MessageLite*>($field$);\n"); " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($field$);\n");
@ -434,6 +443,10 @@ void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
// care when handling them. // care when handling them.
format("if (this != internal_default_instance()) "); format("if (this != internal_default_instance()) ");
} }
if (ShouldSplit(descriptor_, options_)) {
format("delete $cached_split_ptr$->$name$_;\n");
return;
}
format("delete $field$;\n"); format("delete $field$;\n");
} }
@ -504,6 +517,10 @@ void MessageFieldGenerator::GenerateCopyAggregateInitializer(
void MessageFieldGenerator::GenerateAggregateInitializer( void MessageFieldGenerator::GenerateAggregateInitializer(
io::Printer* printer) const { io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
format("decltype(Impl_::Split::$name$_){nullptr}");
return;
}
format("decltype($field$){nullptr}"); format("decltype($field$){nullptr}");
} }

@ -899,11 +899,14 @@ void ParseFunctionGenerator::GenerateFastFieldEntries(Formatter& format) {
if (info.func_name.empty()) { if (info.func_name.empty()) {
format("{::_pbi::TcParser::MiniParse, {}},\n"); format("{::_pbi::TcParser::MiniParse, {}},\n");
} else { } else {
bool cold = ShouldSplit(info.field, options_);
format( format(
"{$1$,\n" "{$1$,\n"
" {$2$, $3$, $4$, PROTOBUF_FIELD_OFFSET($classname$, $5$)}},\n", " {$2$, $3$, $4$, PROTOBUF_FIELD_OFFSET($classname$$5$, $6$)}},\n",
info.func_name, info.coded_tag, info.hasbit_idx, info.aux_idx, info.func_name, info.coded_tag, info.hasbit_idx, info.aux_idx,
FieldMemberName(info.field)); cold ? "::Impl_::Split" : "",
cold ? FieldName(info.field) + "_"
: FieldMemberName(info.field, /*cold=*/false));
} }
} }
} }
@ -1048,8 +1051,11 @@ void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) {
format("/* weak */ 0, 0, 0, 0"); format("/* weak */ 0, 0, 0, 0");
} else { } else {
const OneofDescriptor* oneof = field->real_containing_oneof(); const OneofDescriptor* oneof = field->real_containing_oneof();
format("PROTOBUF_FIELD_OFFSET($classname$, $1$), $2$, $3$,\n ", bool cold = ShouldSplit(field, options_);
FieldMemberName(field), format("PROTOBUF_FIELD_OFFSET($classname$$1$, $2$), $3$, $4$,\n ",
cold ? "::Impl_::Split" : "",
cold ? FieldName(field) + "_"
: FieldMemberName(field, /*cold=*/false),
(oneof ? oneof->index() : entry.hasbit_idx), entry.aux_idx); (oneof ? oneof->index() : entry.hasbit_idx), entry.aux_idx);
FormatFieldKind(format, entry, options_, scc_analyzer_); FormatFieldKind(format, entry, options_, scc_analyzer_);
} }
@ -1550,7 +1556,8 @@ void ParseFunctionGenerator::GenerateFieldSwitch(
format.Indent(); format.Indent();
for (const auto* field : fields) { for (const auto* field : fields) {
format.Set("field", FieldMemberName(field)); bool cold = ShouldSplit(field, options_);
format.Set("field", FieldMemberName(field, cold));
PrintFieldComment(format, field); PrintFieldComment(format, field);
format("case $1$:\n", field->number()); format("case $1$:\n", field->number());
format.Indent(); format.Indent();
@ -1559,6 +1566,9 @@ void ParseFunctionGenerator::GenerateFieldSwitch(
format("if (PROTOBUF_PREDICT_TRUE(static_cast<$uint8$>(tag) == $1$)) {\n", format("if (PROTOBUF_PREDICT_TRUE(static_cast<$uint8$>(tag) == $1$)) {\n",
expected_tag & 0xFF); expected_tag & 0xFF);
format.Indent(); format.Indent();
if (cold) {
format("$msg$PrepareSplitMessageForWrite();\n");
}
auto wiretype = WireFormatLite::GetTagWireType(expected_tag); auto wiretype = WireFormatLite::GetTagWireType(expected_tag);
uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype); uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype);
int tag_size = io::CodedOutputStream::VarintSize32(tag); int tag_size = io::CodedOutputStream::VarintSize32(tag);

@ -105,8 +105,9 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type()); (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type());
(*variables)["default"] = DefaultValue(options, descriptor); (*variables)["default"] = DefaultValue(options, descriptor);
(*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor);
bool cold = ShouldSplit(descriptor, options);
(*variables)["cached_byte_size_field"] = (*variables)["cached_byte_size_field"] =
MakeVarintCachedSizeFieldName(descriptor); MakeVarintCachedSizeFieldName(descriptor, cold);
(*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor)); (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
int fixed_size = FixedSize(descriptor->type()); int fixed_size = FixedSize(descriptor->type());
if (fixed_size != -1) { if (fixed_size != -1) {
@ -165,6 +166,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
" $field$ = value;\n" " $field$ = value;\n"
"}\n" "}\n"
"inline void $classname$::set_$name$($type$ value) {\n" "inline void $classname$::set_$name$($type$ value) {\n"
"$maybe_prepare_split_message$"
" _internal_set_$name$(value);\n" " _internal_set_$name$(value);\n"
"$annotate_set$" "$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n" " // @@protoc_insertion_point(field_set:$full_name$)\n"
@ -233,6 +235,10 @@ void PrimitiveFieldGenerator::GenerateConstexprAggregateInitializer(
void PrimitiveFieldGenerator::GenerateAggregateInitializer( void PrimitiveFieldGenerator::GenerateAggregateInitializer(
io::Printer* printer) const { io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
format("decltype(Impl_::Split::$name$_){$default$}");
return;
}
format("decltype($field$){$default$}"); format("decltype($field$){$default$}");
} }

@ -102,7 +102,9 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override;
void GenerateSwappingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override;
void GenerateConstructorCode(io::Printer* printer) const override {} void GenerateConstructorCode(io::Printer* printer) const override {}
void GenerateCopyConstructorCode(io::Printer* printer) const override {} void GenerateCopyConstructorCode(io::Printer* /*printer*/) const override {
GOOGLE_CHECK(!ShouldSplit(descriptor_, options_));
}
void GenerateDestructorCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override;
void GenerateSerializeWithCachedSizesToArray( void GenerateSerializeWithCachedSizesToArray(
io::Printer* printer) const override; io::Printer* printer) const override;

@ -115,11 +115,7 @@ void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
// allocating arena is null. This is required to support message-owned // allocating arena is null. This is required to support message-owned
// arena (go/path-to-arenas) where a root proto is destroyed but // arena (go/path-to-arenas) where a root proto is destroyed but
// InlinedStringField may have arena-allocated memory. // InlinedStringField may have arena-allocated memory.
// format("::$proto_ns$::internal::InlinedStringField $name$_;\n");
// `_init_inline_xxx` is used for initializing default instances.
format(
"::$proto_ns$::internal::InlinedStringField $name$_;\n"
"static std::true_type _init_inline_$name$_;\n");
} }
} }
@ -130,6 +126,10 @@ void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const {
"static const ::$proto_ns$::internal::LazyString" "static const ::$proto_ns$::internal::LazyString"
" $default_variable_name$;\n"); " $default_variable_name$;\n");
} }
if (inlined_) {
// `_init_inline_xxx` is used for initializing default instances.
format("static std::true_type _init_inline_$name$_;\n");
}
} }
void StringFieldGenerator::GenerateAccessorDeclarations( void StringFieldGenerator::GenerateAccessorDeclarations(
@ -215,6 +215,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
"template <typename ArgT0, typename... ArgT>\n" "template <typename ArgT0, typename... ArgT>\n"
"inline PROTOBUF_ALWAYS_INLINE\n" "inline PROTOBUF_ALWAYS_INLINE\n"
"void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
"$maybe_prepare_split_message$"
" $set_hasbit$\n" " $set_hasbit$\n"
" $field$.$setter$(static_cast<ArgT0 &&>(arg0)," " $field$.$setter$(static_cast<ArgT0 &&>(arg0),"
" args..., GetArenaForAllocation());\n" " args..., GetArenaForAllocation());\n"
@ -226,6 +227,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
"template <typename ArgT0, typename... ArgT>\n" "template <typename ArgT0, typename... ArgT>\n"
"inline PROTOBUF_ALWAYS_INLINE\n" "inline PROTOBUF_ALWAYS_INLINE\n"
"void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
"$maybe_prepare_split_message$"
" $set_hasbit$\n" " $set_hasbit$\n"
" $field$.$setter$(static_cast<ArgT0 &&>(arg0)," " $field$.$setter$(static_cast<ArgT0 &&>(arg0),"
" args..., GetArenaForAllocation(), _internal_$name$_donated(), " " args..., GetArenaForAllocation(), _internal_$name$_donated(), "
@ -240,6 +242,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
} }
format( format(
"inline std::string* $classname$::mutable_$name$() {\n" "inline std::string* $classname$::mutable_$name$() {\n"
"$maybe_prepare_split_message$"
" std::string* _s = _internal_mutable_$name$();\n" " std::string* _s = _internal_mutable_$name$();\n"
"$annotate_mutable$" "$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
@ -280,6 +283,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
format( format(
"inline std::string* $classname$::$release_name$() {\n" "inline std::string* $classname$::$release_name$() {\n"
"$annotate_release$" "$annotate_release$"
"$maybe_prepare_split_message$"
" // @@protoc_insertion_point(field_release:$full_name$)\n"); " // @@protoc_insertion_point(field_release:$full_name$)\n");
if (HasHasbit(descriptor_)) { if (HasHasbit(descriptor_)) {
@ -311,6 +315,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
format( format(
"}\n" "}\n"
"inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
"$maybe_prepare_split_message$"
" if ($name$ != nullptr) {\n" " if ($name$ != nullptr) {\n"
" $set_hasbit$\n" " $set_hasbit$\n"
" } else {\n" " } else {\n"
@ -440,6 +445,21 @@ void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
} }
} }
void StringFieldGenerator::GenerateCreateSplitMessageCode(
io::Printer* printer) const {
GOOGLE_CHECK(ShouldSplit(descriptor_, options_));
GOOGLE_CHECK(!inlined_);
Formatter format(printer, variables_);
format("ptr->$name$_.InitDefault();\n");
if (IsString(descriptor_, options_) &&
descriptor_->default_value_string().empty()) {
format(
"#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"
" ptr->$name$_.Set(\"\", GetArenaForAllocation());\n"
"#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
}
}
void StringFieldGenerator::GenerateCopyConstructorCode( void StringFieldGenerator::GenerateCopyConstructorCode(
io::Printer* printer) const { io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
@ -474,6 +494,10 @@ void StringFieldGenerator::GenerateCopyConstructorCode(
void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (!inlined_) { if (!inlined_) {
if (ShouldSplit(descriptor_, options_)) {
format("$cached_split_ptr$->$name$_.Destroy();\n");
return;
}
format("$field$.Destroy();\n"); format("$field$.Destroy();\n");
return; return;
} }
@ -481,6 +505,7 @@ void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
// Destructor has been implicitly skipped as a union, and even the // Destructor has been implicitly skipped as a union, and even the
// message-owned arena is enabled, arena could still be missing for // message-owned arena is enabled, arena could still be missing for
// Arena::CreateMessage(nullptr). // Arena::CreateMessage(nullptr).
GOOGLE_DCHECK(!ShouldSplit(descriptor_, options_));
format("$field$.~InlinedStringField();\n"); format("$field$.~InlinedStringField();\n");
} }
@ -541,6 +566,11 @@ void StringFieldGenerator::GenerateConstexprAggregateInitializer(
void StringFieldGenerator::GenerateAggregateInitializer( void StringFieldGenerator::GenerateAggregateInitializer(
io::Printer* printer) const { io::Printer* printer) const {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (ShouldSplit(descriptor_, options_)) {
GOOGLE_CHECK(!inlined_);
format("decltype(Impl_::Split::$name$_){}");
return;
}
if (!inlined_) { if (!inlined_) {
format("decltype($field$){}"); format("decltype($field$){}");
} else { } else {

@ -63,6 +63,7 @@ class StringFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override;
void GenerateSwappingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override;
void GenerateConstructorCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override;
void GenerateCreateSplitMessageCode(io::Printer* printer) const override;
void GenerateCopyConstructorCode(io::Printer* printer) const override; void GenerateCopyConstructorCode(io::Printer* printer) const override;
void GenerateDestructorCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override;
void GenerateArenaDestructorCode(io::Printer* printer) const override; void GenerateArenaDestructorCode(io::Printer* printer) const override;
@ -115,7 +116,9 @@ class RepeatedStringFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override;
void GenerateSwappingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override;
void GenerateConstructorCode(io::Printer* printer) const override {} void GenerateConstructorCode(io::Printer* printer) const override {}
void GenerateCopyConstructorCode(io::Printer* printer) const override {} void GenerateCopyConstructorCode(io::Printer* /*printer*/) const override {
GOOGLE_CHECK(!ShouldSplit(descriptor_, options_));
}
void GenerateDestructorCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override;
void GenerateSerializeWithCachedSizesToArray( void GenerateSerializeWithCachedSizesToArray(
io::Printer* printer) const override; io::Printer* printer) const override;

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> #include <google/protobuf/compiler/csharp/csharp_primitive_field.h>

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h> #include <google/protobuf/compiler/csharp/csharp_field_base.h>

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h> #include <google/protobuf/compiler/csharp/csharp_field_base.h>

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h> #include <google/protobuf/compiler/csharp/csharp_field_base.h>

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h> #include <google/protobuf/compiler/csharp/csharp_field_base.h>

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h> #include <google/protobuf/compiler/csharp/csharp_field_base.h>

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h> #include <google/protobuf/compiler/csharp/csharp_field_base.h>

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h> #include <google/protobuf/compiler/csharp/csharp_field_base.h>

@ -117,46 +117,77 @@ bool FileContainsExtensions(const FileDescriptor* file) {
return false; return false;
} }
// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) {
// deps as visited and prunes them from the needed files list.
void PruneFileAndDepsMarkingAsVisited(
const FileDescriptor* file,
std::vector<const FileDescriptor*>* files,
std::set<const FileDescriptor*>* files_visited) {
std::vector<const FileDescriptor*>::iterator iter =
std::find(files->begin(), files->end(), file);
if (iter != files->end()) {
files->erase(iter);
}
files_visited->insert(file);
for (int i = 0; i < file->dependency_count(); i++) { for (int i = 0; i < file->dependency_count(); i++) {
PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited); if (dep == file->dependency(i)) {
return true;
}
} }
return false;
} }
// Helper for CollectMinimalFileDepsContainingExtensions. struct FileDescriptorsOrderedByName {
void CollectMinimalFileDepsContainingExtensionsWorker( inline bool operator()(const FileDescriptor* a,
const FileDescriptor* file, const FileDescriptor* b) const {
std::vector<const FileDescriptor*>* files, return a->name() < b->name();
std::set<const FileDescriptor*>* files_visited) { }
if (files_visited->find(file) != files_visited->end()) { };
return;
} } // namespace
files_visited->insert(file);
FileGenerator::CommonState::CommonState() { }
if (FileContainsExtensions(file)) {
files->push_back(file); const FileGenerator::CommonState::MinDepsEntry&
for (int i = 0; i < file->dependency_count(); i++) { FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal(
const FileDescriptor* dep = file->dependency(i); const FileDescriptor* file) {
PruneFileAndDepsMarkingAsVisited(dep, files, files_visited); auto it = deps_info_cache_.find(file);
} if (it != deps_info_cache_.end()) {
} else { return it->second;
for (int i = 0; i < file->dependency_count(); i++) { }
const FileDescriptor* dep = file->dependency(i);
CollectMinimalFileDepsContainingExtensionsWorker(dep, files, std::set<const FileDescriptor*> min_deps_collector;
files_visited); std::set<const FileDescriptor*> covered_deps_collector;
std::set<const FileDescriptor*> to_prune;
for (int i = 0; i < file->dependency_count(); i++) {
const FileDescriptor* dep = file->dependency(i);
MinDepsEntry dep_info =
CollectMinimalFileDepsContainingExtensionsInternal(dep);
// Everything the dep covered, this file will also cover.
covered_deps_collector.insert(dep_info.covered_deps.begin(), dep_info.covered_deps.end());
// Prune everything from the dep's covered list in case another dep lists it
// as a min dep.
to_prune.insert(dep_info.covered_deps.begin(), dep_info.covered_deps.end());
// Does the dep have any extensions...
if (dep_info.has_extensions) {
// Yes -> Add this file, prune its min_deps and add them to the covered deps.
min_deps_collector.insert(dep);
to_prune.insert(dep_info.min_deps.begin(), dep_info.min_deps.end());
covered_deps_collector.insert(dep_info.min_deps.begin(), dep_info.min_deps.end());
} else {
// No -> Just use its min_deps.
min_deps_collector.insert(dep_info.min_deps.begin(), dep_info.min_deps.end());
} }
} }
const bool file_has_exts = FileContainsExtensions(file);
// Fast path: if nothing to prune or there was only one dep, the prune work is
// a waste, skip it.
if (to_prune.empty() || file->dependency_count() == 1) {
return deps_info_cache_.insert(
{file, {file_has_exts, min_deps_collector, covered_deps_collector}}).first->second;
}
std::set<const FileDescriptor*> min_deps;
std::copy_if(min_deps_collector.begin(), min_deps_collector.end(),
std::inserter(min_deps, min_deps.end()),
[&](const FileDescriptor* value){
return to_prune.find(value) == to_prune.end();
});
return deps_info_cache_.insert(
{file, {file_has_exts, min_deps, covered_deps_collector}}).first->second;
} }
// Collect the deps of the given file that contain extensions. This can be used to // Collect the deps of the given file that contain extensions. This can be used to
@ -168,32 +199,23 @@ void CollectMinimalFileDepsContainingExtensionsWorker(
// There are comments about what the expected code should be line and limited // There are comments about what the expected code should be line and limited
// testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports // testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports
// specifically). // specifically).
void CollectMinimalFileDepsContainingExtensions( const std::vector<const FileDescriptor*>
const FileDescriptor* file, FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensions(
std::vector<const FileDescriptor*>* files) { const FileDescriptor* file) {
std::set<const FileDescriptor*> files_visited; std::set<const FileDescriptor*> min_deps =
for (int i = 0; i < file->dependency_count(); i++) { CollectMinimalFileDepsContainingExtensionsInternal(file).min_deps;
const FileDescriptor* dep = file->dependency(i); // Sort the list since pointer order isn't stable across runs.
CollectMinimalFileDepsContainingExtensionsWorker(dep, files, std::vector<const FileDescriptor*> result(min_deps.begin(), min_deps.end());
&files_visited); std::sort(result.begin(), result.end(), FileDescriptorsOrderedByName());
} return result;
} }
bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) {
for (int i = 0; i < file->dependency_count(); i++) {
if (dep == file->dependency(i)) {
return true;
}
}
return false;
}
} // namespace
FileGenerator::FileGenerator(const FileDescriptor* file, FileGenerator::FileGenerator(const FileDescriptor* file,
const GenerationOptions& generation_options) const GenerationOptions& generation_options,
CommonState& common_state)
: file_(file), : file_(file),
generation_options_(generation_options), generation_options_(generation_options),
common_state_(common_state),
root_class_name_(FileClassName(file)), root_class_name_(FileClassName(file)),
is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) { is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) {
for (int i = 0; i < file_->enum_type_count(); i++) { for (int i = 0; i < file_->enum_type_count(); i++) {
@ -374,8 +396,8 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"\n"); "\n");
} }
std::vector<const FileDescriptor*> deps_with_extensions; std::vector<const FileDescriptor*> deps_with_extensions =
CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); common_state_.CollectMinimalFileDepsContainingExtensions(file_);
// The bundled protos (WKTs) don't use of forward declarations. // The bundled protos (WKTs) don't use of forward declarations.
bool headers_use_forward_declarations = bool headers_use_forward_declarations =

@ -31,8 +31,9 @@
#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 <string> #include <map>
#include <set> #include <set>
#include <string>
#include <vector> #include <vector>
#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
@ -59,8 +60,29 @@ class FileGenerator {
bool headers_use_forward_declarations; bool headers_use_forward_declarations;
}; };
// Wrapper for some common state that is shared between file generations to
// improve performance when more than one file is generated at a time.
struct CommonState {
CommonState();
const std::vector<const FileDescriptor*>
CollectMinimalFileDepsContainingExtensions(const FileDescriptor* file);
private:
struct MinDepsEntry {
bool has_extensions;
std::set<const FileDescriptor*> min_deps;
// `covered_deps` are the transtive deps of `min_deps_w_exts` that also
// have extensions.
std::set<const FileDescriptor*> covered_deps;
};
const MinDepsEntry& CollectMinimalFileDepsContainingExtensionsInternal(const FileDescriptor* file);
std::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);
~FileGenerator(); ~FileGenerator();
FileGenerator(const FileGenerator&) = delete; FileGenerator(const FileGenerator&) = delete;
@ -72,6 +94,7 @@ class FileGenerator {
private: private:
const FileDescriptor* file_; const FileDescriptor* file_;
const GenerationOptions& generation_options_; const GenerationOptions& generation_options_;
CommonState& common_state_;
std::string root_class_name_; std::string root_class_name_;
bool is_bundled_proto_; bool is_bundled_proto_;

@ -269,9 +269,10 @@ bool ObjectiveCGenerator::GenerateAll(
return false; return false;
} }
FileGenerator::CommonState state;
for (int i = 0; i < files.size(); i++) { for (int i = 0; i < files.size(); i++) {
const FileDescriptor* file = files[i]; const FileDescriptor* file = files[i];
FileGenerator file_generator(file, generation_options); FileGenerator file_generator(file, generation_options, state);
std::string filepath = FilePath(file); std::string filepath = FilePath(file);
// Generate header. // Generate header.

@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
#include <map>
#include <string>
#include <google/protobuf/compiler/objectivec/objectivec_field.h> #include <google/protobuf/compiler/objectivec/objectivec_field.h>
namespace google { namespace google {

@ -1286,4 +1286,133 @@ message TestExtensionRangeSerialize {
} }
} }
message TestVerifyInt32Simple {
optional int32 optional_int32_1 = 1;
optional int32 optional_int32_2 = 2;
optional int32 optional_int32_63 = 63;
optional int32 optional_int32_64 = 64;
}
message TestVerifyInt32 {
optional int32 optional_int32_1 = 1;
optional int32 optional_int32_2 = 2;
optional int32 optional_int32_63 = 63;
optional int32 optional_int32_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyMostlyInt32 {
optional int64 optional_int64_30 = 30;
optional int32 optional_int32_1 = 1;
optional int32 optional_int32_2 = 2;
optional int32 optional_int32_3 = 3;
optional int32 optional_int32_4 = 4;
optional int32 optional_int32_63 = 63;
optional int32 optional_int32_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyMostlyInt32BigFieldNumber {
optional int64 optional_int64_30 = 30;
optional int32 optional_int32_300 = 300;
optional int32 optional_int32_1 = 1;
optional int32 optional_int32_2 = 2;
optional int32 optional_int32_3 = 3;
optional int32 optional_int32_4 = 4;
optional int32 optional_int32_63 = 63;
optional int32 optional_int32_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyUint32Simple {
optional uint32 optional_uint32_1 = 1;
optional uint32 optional_uint32_2 = 2;
optional uint32 optional_uint32_63 = 63;
optional uint32 optional_uint32_64 = 64;
}
message TestVerifyUint32 {
optional uint32 optional_uint32_1 = 1;
optional uint32 optional_uint32_2 = 2;
optional uint32 optional_uint32_63 = 63;
optional uint32 optional_uint32_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyOneUint32 {
optional uint32 optional_uint32_1 = 1;
optional int32 optional_int32_2 = 2;
optional int32 optional_int32_63 = 63;
optional int32 optional_int32_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyOneInt32BigFieldNumber {
optional int32 optional_int32_65 = 65;
optional int64 optional_int64_1 = 1;
optional int64 optional_int64_2 = 2;
optional int64 optional_int64_63 = 63;
optional int64 optional_int64_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyInt32BigFieldNumber {
optional int32 optional_int32_1000 = 1000;
optional int32 optional_int32_65 = 65;
optional int32 optional_int32_1 = 1;
optional int32 optional_int32_2 = 2;
optional int32 optional_int32_63 = 63;
optional int32 optional_int32_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyUint32BigFieldNumber {
optional uint32 optional_uint32_1000 = 1000;
optional uint32 optional_uint32_65 = 65;
optional uint32 optional_uint32_1 = 1;
optional uint32 optional_uint32_2 = 2;
optional uint32 optional_uint32_63 = 63;
optional uint32 optional_uint32_64 = 64;
optional TestAllTypes optional_all_types = 9;
repeated TestAllTypes repeated_all_types = 10;
}
message TestVerifyBigFieldNumberUint32 {
message Nested {
optional uint32 optional_uint32_5000 = 5000;
optional uint32 optional_uint32_1000 = 1000;
optional uint32 optional_uint32_66 = 66;
optional uint32 optional_uint32_65 = 65;
optional uint32 optional_uint32_1 = 1;
optional uint32 optional_uint32_2 = 2;
optional uint32 optional_uint32_63 = 63;
optional uint32 optional_uint32_64 = 64;
optional Nested optional_nested = 9;
repeated Nested repeated_nested = 10;
}
optional Nested optional_nested = 1;
}

@ -349,10 +349,6 @@ build_objectivec_tvos_release() {
build_objectivec_tvos --skip-xcode-debug build_objectivec_tvos --skip-xcode-debug
} }
build_objectivec_cocoapods_integration() {
objectivec/Tests/CocoaPods/run_tests.sh
}
build_python() { build_python() {
internal_build_cpp internal_build_cpp
cd python cd python
@ -597,7 +593,6 @@ Usage: $0 { cpp |
objectivec_tvos | objectivec_tvos |
objectivec_tvos_debug | objectivec_tvos_debug |
objectivec_tvos_release | objectivec_tvos_release |
objectivec_cocoapods_integration |
python | python |
python_cpp | python_cpp |
python_compatibility | python_compatibility |

Loading…
Cancel
Save