Sync from Piper @mkruskal/footmitten

PROTOBUF_SYNC_PIPER
pull/10729/head
Mike Kruskal 3 years ago
parent b0c76ccc21
commit 388e3d744f
  1. 8
      Protobuf.podspec
  2. 21
      cmake/README.md
  3. 41
      cmake/push_auto_update.sh
  4. 146
      java/core/src/main/java/com/google/protobuf/ArrayDecoders.java
  5. 32
      java/core/src/main/java/com/google/protobuf/BinaryReader.java
  6. 51
      java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java
  7. 1
      java/core/src/main/java/com/google/protobuf/ExtensionSchema.java
  8. 5
      java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java
  9. 17
      java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java
  10. 167
      java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  11. 117
      java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
  12. 485
      java/core/src/main/java/com/google/protobuf/MessageSchema.java
  13. 17
      java/core/src/main/java/com/google/protobuf/MessageSetSchema.java
  14. 5
      java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java
  15. 8
      java/core/src/main/java/com/google/protobuf/Reader.java
  16. 32
      java/core/src/main/java/com/google/protobuf/SchemaUtil.java
  17. 39
      java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java
  18. 12
      java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java
  19. 21
      java/lite/src/test/java/com/google/protobuf/LiteTest.java
  20. 2
      java/protoc/pom.xml
  21. 4
      kokoro/release/collect_all_artifacts.sh
  22. 0
      kokoro/release/protoc/build-protoc.sh
  23. 10
      kokoro/release/protoc/linux/build.sh
  24. 34
      kokoro/windows/cmake_nmake/build.bat
  25. 5
      kokoro/windows/cmake_nmake/common.cfg
  26. 1
      kokoro/windows/cmake_nmake/continuous.cfg
  27. 1
      kokoro/windows/cmake_nmake/presubmit.cfg
  28. 28
      objectivec/DevTools/full_mac_build.sh
  29. 170
      objectivec/GPBCodedOutputStream.m
  30. 6
      objectivec/GPBDescriptor.m
  31. 343
      objectivec/GPBDictionary.m
  32. 16
      objectivec/GPBMessage.m
  33. 12
      objectivec/GPBRootObject.m
  34. 52
      objectivec/GPBUnknownField.m
  35. 18
      objectivec/GPBUnknownFieldSet.m
  36. 50
      objectivec/GPBUtilities.m
  37. 33
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
  38. 33
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  39. 33
      objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj
  40. 2
      objectivec/README.md
  41. 54
      objectivec/Tests/GPBArrayTests.m
  42. 48
      objectivec/Tests/GPBDictionaryTests+Bool.m
  43. 57
      objectivec/Tests/GPBDictionaryTests+Int32.m
  44. 57
      objectivec/Tests/GPBDictionaryTests+Int64.m
  45. 51
      objectivec/Tests/GPBDictionaryTests+String.m
  46. 57
      objectivec/Tests/GPBDictionaryTests+UInt32.m
  47. 57
      objectivec/Tests/GPBDictionaryTests+UInt64.m
  48. 15
      objectivec/Tests/GPBDictionaryTests.pddm
  49. 3
      objectivec/Tests/GPBMessageTests+Runtime.m
  50. 9
      objectivec/Tests/GPBMessageTests.m
  51. 21
      pkg/BUILD.bazel
  52. 161
      protoc-artifacts/README.md
  53. 120
      protoc-artifacts/build-zip.sh
  54. 144
      protoc-artifacts/pom.xml
  55. 13
      protoc-artifacts/scl-enable-devtoolset.sh
  56. 9
      src/file_lists.cmake
  57. 50
      src/google/protobuf/arena.cc
  58. 31
      src/google/protobuf/arena_impl.h
  59. 1
      src/google/protobuf/compiler/BUILD.bazel
  60. 2
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  61. 38
      src/google/protobuf/compiler/cpp/BUILD.bazel
  62. 15
      src/google/protobuf/compiler/csharp/BUILD.bazel
  63. 2
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  64. 3
      src/google/protobuf/compiler/csharp/csharp_generator.cc
  65. 167
      src/google/protobuf/compiler/csharp/csharp_helpers.cc
  66. 22
      src/google/protobuf/compiler/csharp/csharp_helpers.h
  67. 2
      src/google/protobuf/compiler/csharp/csharp_message.cc
  68. 2
      src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
  69. 2
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
  70. 225
      src/google/protobuf/compiler/csharp/names.cc
  71. 42
      src/google/protobuf/compiler/csharp/names.h
  72. 43
      src/google/protobuf/compiler/java/BUILD.bazel
  73. 6
      src/google/protobuf/compiler/java/context.cc
  74. 15
      src/google/protobuf/compiler/java/context.h
  75. 4
      src/google/protobuf/compiler/java/enum_field.cc
  76. 2
      src/google/protobuf/compiler/java/enum_field_lite.cc
  77. 136
      src/google/protobuf/compiler/java/helpers.cc
  78. 31
      src/google/protobuf/compiler/java/helpers.h
  79. 2
      src/google/protobuf/compiler/java/message.cc
  80. 3
      src/google/protobuf/compiler/java/message_builder.cc
  81. 2
      src/google/protobuf/compiler/java/message_lite.cc
  82. 193
      src/google/protobuf/compiler/java/names.cc
  83. 32
      src/google/protobuf/compiler/java/names.h
  84. 3
      src/google/protobuf/compiler/java/primitive_field.cc
  85. 2
      src/google/protobuf/compiler/java/string_field.cc
  86. 32
      src/google/protobuf/compiler/objectivec/BUILD.bazel
  87. 2
      src/google/protobuf/compiler/objectivec/names.cc
  88. 363
      src/google/protobuf/compiler/objectivec/names.h
  89. 312
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h
  90. 60
      src/google/protobuf/compiler/parser.cc
  91. 4
      src/google/protobuf/compiler/parser.h
  92. 142
      src/google/protobuf/compiler/parser_unittest.cc
  93. 15
      src/google/protobuf/compiler/php/BUILD.bazel
  94. 144
      src/google/protobuf/compiler/php/names.cc
  95. 73
      src/google/protobuf/compiler/php/names.h
  96. 116
      src/google/protobuf/compiler/php/php_generator.cc
  97. 8
      src/google/protobuf/compiler/php/php_generator.h
  98. 1
      src/google/protobuf/compiler/python/BUILD.bazel
  99. 190
      src/google/protobuf/descriptor.cc
  100. 88
      src/google/protobuf/descriptor_unittest.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -34,10 +34,10 @@ Pod::Spec.new do |s|
s.user_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
s.ios.deployment_target = '9.0'
s.osx.deployment_target = '10.9'
s.tvos.deployment_target = '9.0'
s.watchos.deployment_target = '2.0'
s.ios.deployment_target = '10.0'
s.osx.deployment_target = '10.12'
s.tvos.deployment_target = '12.0'
s.watchos.deployment_target = '6.0'
s.requires_arc = false
# The unittest need the generate sources from the testing related .proto

@ -89,9 +89,6 @@ for various native build systems.
Of most interest to Windows programmers are the following:
* [Makefile](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#makefile-generators).
This generates NMake Makefiles for Visual Studio. These work, but they are rather slow.
* [Visual Studio](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators)
This generates a Visual Studio solution for the project.
@ -112,16 +109,6 @@ Create a temporary *build* folder and change your working directory to it:
The *Makefile* and *Ninja* generators can build the project in only one configuration, so you need to build
a separate folder for each configuration.
To start using a *Release* configuration via the *NMmake* generator:
C:\Path\to\build\protobuf>mkdir release & cd release
C:\Path\to\build\protobuf\release>cmake -G "NMake Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
C:\Path\to\src\protobuf
It will generate a *NMake* *Makefile* in the current directory.
To use *Debug* configuration using *Ninja*:
C:\Path\to\build\protobuf>mkdir debug & cd debug
@ -192,10 +179,6 @@ Note that if your generator supports multiple configurations, you will probably
You can also run directly the build tool you've configured:
C:\Path\to\build\protobuf\release>nmake
or
C:\Path\to\build\protobuf\debug>ninja
And wait for the compilation to finish.
@ -268,10 +251,6 @@ To install protobuf to the *install* folder you've specified in the configuratio
Or if you prefer:
C:\Path\to\build\protobuf\release>nmake install
or
C:\Path\to\build\protobuf\debug>ninja install
You can also build project *INSTALL* from Visual Studio solution.

@ -1,41 +0,0 @@
#!/bin/bash
# This script updates the CMake file lists (i.e. src/file_lists.cmake), commits
# the resulting change, and pushes it. This does not do anything useful when
# run manually, but should be run by our GitHub action instead.
set -ex
# Exit early if the previous commit was made by the bot. This reduces the risk
# of a bug causing an infinite loop of auto-generated commits.
if (git log -1 --pretty=format:'%an' | grep -q "Protobuf Team Bot"); then
echo "Previous commit was authored by bot"
exit 0
fi
$(dirname -- "$0")/update_file_lists.sh
# Try to determine the most recent pull request number.
title=$(git log -1 --pretty='%s')
pr_from_merge=$(echo "$title" | sed -n 's/^Merge pull request #\([0-9]\+\).*/\1/p')
pr_from_squash=$(echo "$title" | sed -n 's/^.*(#\([0-9]\+\))$/\1/p')
pr=""
if [ ! -z "$pr_from_merge" ]; then
pr="$pr_from_merge"
elif [ ! -z "$pr_from_squash" ]; then
pr="$pr_from_squash"
fi
if [ ! -z "$pr" ]; then
commit_message="Auto-generate CMake file lists after PR #$pr"
else
# If we are unable to determine the pull request number, we fall back on this
# default commit message. Typically this should not occur, but could happen
# if a pull request was merged via a rebase.
commit_message="Auto-generate CMake file lists"
fi
git add -A
git diff --staged --quiet || git commit -am "$commit_message"
git push

@ -237,6 +237,29 @@ final class ArrayDecoders {
@SuppressWarnings({"unchecked", "rawtypes"})
static int decodeMessageField(
Schema schema, byte[] data, int position, int limit, Registers registers) throws IOException {
Object msg = schema.newInstance();
int offset = mergeMessageField(msg, schema, data, position, limit, registers);
schema.makeImmutable(msg);
registers.object1 = msg;
return offset;
}
/** Decodes a group value. */
@SuppressWarnings({"unchecked", "rawtypes"})
static int decodeGroupField(
Schema schema, byte[] data, int position, int limit, int endGroup, Registers registers)
throws IOException {
Object msg = schema.newInstance();
int offset = mergeGroupField(msg, schema, data, position, limit, endGroup, registers);
schema.makeImmutable(msg);
registers.object1 = msg;
return offset;
}
@SuppressWarnings({"unchecked", "rawtypes"})
static int mergeMessageField(
Object msg, Schema schema, byte[] data, int position, int limit, Registers registers)
throws IOException {
int length = data[position++];
if (length < 0) {
position = decodeVarint32(length, data, position, registers);
@ -245,27 +268,28 @@ final class ArrayDecoders {
if (length < 0 || length > limit - position) {
throw InvalidProtocolBufferException.truncatedMessage();
}
Object result = schema.newInstance();
schema.mergeFrom(result, data, position, position + length, registers);
schema.makeImmutable(result);
registers.object1 = result;
schema.mergeFrom(msg, data, position, position + length, registers);
registers.object1 = msg;
return position + length;
}
/** Decodes a group value. */
@SuppressWarnings({"unchecked", "rawtypes"})
static int decodeGroupField(
Schema schema, byte[] data, int position, int limit, int endGroup, Registers registers)
static int mergeGroupField(
Object msg,
Schema schema,
byte[] data,
int position,
int limit,
int endGroup,
Registers registers)
throws IOException {
// A group field must has a MessageSchema (the only other subclass of Schema is MessageSetSchema
// and it can't be used in group fields).
final MessageSchema messageSchema = (MessageSchema) schema;
Object result = messageSchema.newInstance();
// It's OK to directly use parseProto2Message since proto3 doesn't have group.
final int endPosition =
messageSchema.parseProto2Message(result, data, position, limit, endGroup, registers);
messageSchema.makeImmutable(result);
registers.object1 = result;
messageSchema.parseProto2Message(msg, data, position, limit, endGroup, registers);
registers.object1 = msg;
return endPosition;
}
@ -851,26 +875,19 @@ final class ArrayDecoders {
break;
}
case ENUM:
{
IntArrayList list = new IntArrayList();
position = decodePackedVarint32List(data, position, list, registers);
UnknownFieldSetLite unknownFields = message.unknownFields;
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = null;
}
unknownFields =
SchemaUtil.filterUnknownEnumList(
fieldNumber,
list,
extension.descriptor.getEnumType(),
unknownFields,
unknownFieldSchema);
if (unknownFields != null) {
message.unknownFields = unknownFields;
{
IntArrayList list = new IntArrayList();
position = decodePackedVarint32List(data, position, list, registers);
SchemaUtil.filterUnknownEnumList(
message,
fieldNumber,
list,
extension.descriptor.getEnumType(),
null,
unknownFieldSchema);
extensions.setField(extension.descriptor, list);
break;
}
extensions.setField(extension.descriptor, list);
break;
}
default:
throw new IllegalStateException(
"Type cannot be packed: " + extension.descriptor.getLiteType());
@ -882,13 +899,8 @@ final class ArrayDecoders {
position = decodeVarint32(data, position, registers);
Object enumValue = extension.descriptor.getEnumType().findValueByNumber(registers.int1);
if (enumValue == null) {
UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
((GeneratedMessageLite) message).unknownFields = unknownFields;
}
SchemaUtil.storeUnknownEnum(
fieldNumber, registers.int1, unknownFields, unknownFieldSchema);
message, fieldNumber, registers.int1, null, unknownFieldSchema);
return position;
}
// Note, we store the integer value instead of the actual enum object in FieldSet.
@ -945,20 +957,45 @@ final class ArrayDecoders {
value = registers.object1;
break;
case GROUP:
final int endTag = (fieldNumber << 3) | WireFormat.WIRETYPE_END_GROUP;
position = decodeGroupField(
Protobuf.getInstance().schemaFor(extension.getMessageDefaultInstance().getClass()),
data, position, limit, endTag, registers);
value = registers.object1;
break;
{
final int endTag = (fieldNumber << 3) | WireFormat.WIRETYPE_END_GROUP;
final Schema fieldSchema =
Protobuf.getInstance()
.schemaFor(extension.getMessageDefaultInstance().getClass());
if (extension.isRepeated()) {
position = decodeGroupField(fieldSchema, data, position, limit, endTag, registers);
extensions.addRepeatedField(extension.descriptor, registers.object1);
} else {
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue == null) {
oldValue = fieldSchema.newInstance();
extensions.setField(extension.descriptor, oldValue);
}
position =
mergeGroupField(
oldValue, fieldSchema, data, position, limit, endTag, registers);
}
return position;
}
case MESSAGE:
position = decodeMessageField(
Protobuf.getInstance().schemaFor(extension.getMessageDefaultInstance().getClass()),
data, position, limit, registers);
value = registers.object1;
break;
{
final Schema fieldSchema =
Protobuf.getInstance()
.schemaFor(extension.getMessageDefaultInstance().getClass());
if (extension.isRepeated()) {
position = decodeMessageField(fieldSchema, data, position, limit, registers);
extensions.addRepeatedField(extension.descriptor, registers.object1);
} else {
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue == null) {
oldValue = fieldSchema.newInstance();
extensions.setField(extension.descriptor, oldValue);
}
position =
mergeMessageField(oldValue, fieldSchema, data, position, limit, registers);
}
return position;
}
case ENUM:
throw new IllegalStateException("Shouldn't reach here.");
}
@ -966,17 +1003,6 @@ final class ArrayDecoders {
if (extension.isRepeated()) {
extensions.addRepeatedField(extension.descriptor, value);
} else {
switch (extension.getLiteType()) {
case MESSAGE:
case GROUP:
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue != null) {
value = Internal.mergeMessage(oldValue, value);
}
break;
default:
break;
}
extensions.setField(extension.descriptor, value);
}
}

@ -248,6 +248,15 @@ abstract class BinaryReader implements Reader {
private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException {
T newInstance = schema.newInstance();
mergeMessageField(newInstance, schema, extensionRegistry);
schema.makeImmutable(newInstance);
return newInstance;
}
@Override
public <T> void mergeMessageField(
T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
int size = readVarint32();
requireBytes(size);
@ -257,15 +266,10 @@ abstract class BinaryReader implements Reader {
limit = newLimit;
try {
// Allocate and read the message.
T message = schema.newInstance();
schema.mergeFrom(message, this, extensionRegistry);
schema.makeImmutable(message);
schema.mergeFrom(target, this, extensionRegistry);
if (pos != newLimit) {
throw InvalidProtocolBufferException.parseFailure();
}
return message;
} finally {
// Restore the limit.
limit = prevLimit;
@ -290,19 +294,23 @@ abstract class BinaryReader implements Reader {
private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException {
T newInstance = schema.newInstance();
mergeGroupField(newInstance, schema, extensionRegistry);
schema.makeImmutable(newInstance);
return newInstance;
}
@Override
public <T> void mergeGroupField(
T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
int prevEndGroupTag = endGroupTag;
endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP);
try {
// Allocate and read the message.
T message = schema.newInstance();
schema.mergeFrom(message, this, extensionRegistry);
schema.makeImmutable(message);
schema.mergeFrom(target, this, extensionRegistry);
if (tag != endGroupTag) {
throw InvalidProtocolBufferException.parseFailure();
}
return message;
} finally {
// Restore the old end group tag.
endGroupTag = prevEndGroupTag;

@ -197,9 +197,15 @@ final class CodedInputStreamReader implements Reader {
return readGroup(schema, extensionRegistry);
}
// Should have the same semantics of CodedInputStream#readMessage()
private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException {
@Override
public <T> void mergeMessageField(
T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
requireWireType(WIRETYPE_LENGTH_DELIMITED);
mergeMessageFieldInternal(target, schema, extensionRegistry);
}
private <T> void mergeMessageFieldInternal(
T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
int size = input.readUInt32();
if (input.recursionDepth >= input.recursionLimit) {
throw InvalidProtocolBufferException.recursionLimitExceeded();
@ -207,39 +213,54 @@ final class CodedInputStreamReader implements Reader {
// Push the new limit.
final int prevLimit = input.pushLimit(size);
// Allocate and read the message.
T message = schema.newInstance();
++input.recursionDepth;
schema.mergeFrom(message, this, extensionRegistry);
schema.makeImmutable(message);
schema.mergeFrom(target, this, extensionRegistry);
input.checkLastTagWas(0);
--input.recursionDepth;
// Restore the previous limit.
input.popLimit(prevLimit);
return message;
}
private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
// Should have the same semantics of CodedInputStream#readMessage()
private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException {
T newInstance = schema.newInstance();
mergeMessageFieldInternal(newInstance, schema, extensionRegistry);
schema.makeImmutable(newInstance);
return newInstance;
}
@Override
public <T> void mergeGroupField(
T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
requireWireType(WIRETYPE_START_GROUP);
mergeGroupFieldInternal(target, schema, extensionRegistry);
}
private <T> void mergeGroupFieldInternal(
T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
int prevEndGroupTag = endGroupTag;
endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP);
try {
// Allocate and read the message.
T message = schema.newInstance();
schema.mergeFrom(message, this, extensionRegistry);
schema.makeImmutable(message);
schema.mergeFrom(target, this, extensionRegistry);
if (tag != endGroupTag) {
throw InvalidProtocolBufferException.parseFailure();
}
return message;
} finally {
// Restore the old end group tag.
endGroupTag = prevEndGroupTag;
}
}
private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException {
T newInstance = schema.newInstance();
mergeGroupFieldInternal(newInstance, schema, extensionRegistry);
schema.makeImmutable(newInstance);
return newInstance;
}
@Override
public ByteString readBytes() throws IOException {
requireWireType(WIRETYPE_LENGTH_DELIMITED);

@ -60,6 +60,7 @@ abstract class ExtensionSchema<T extends FieldSet.FieldDescriptorLite<T>> {
* or UnknownFieldSetLite in lite runtime.
*/
abstract <UT, UB> UB parseExtension(
Object containerMessage,
Reader reader,
Object extension,
ExtensionRegistryLite extensionRegistry,

@ -85,6 +85,7 @@ final class ExtensionSchemaFull extends ExtensionSchema<FieldDescriptor> {
@Override
<UT, UB> UB parseExtension(
Object containerMessage,
Reader reader,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
@ -202,7 +203,7 @@ final class ExtensionSchemaFull extends ExtensionSchema<FieldDescriptor> {
} else {
unknownFields =
SchemaUtil.storeUnknownEnum(
fieldNumber, number, unknownFields, unknownFieldSchema);
containerMessage, fieldNumber, number, unknownFields, unknownFieldSchema);
}
}
value = enumList;
@ -221,7 +222,7 @@ final class ExtensionSchemaFull extends ExtensionSchema<FieldDescriptor> {
Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number);
if (enumValue == null) {
return SchemaUtil.storeUnknownEnum(
fieldNumber, number, unknownFields, unknownFieldSchema);
containerMessage, fieldNumber, number, unknownFields, unknownFieldSchema);
}
value = enumValue;
} else {

@ -32,7 +32,6 @@ package com.google.protobuf;
import com.google.protobuf.GeneratedMessageLite.ExtensionDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -68,6 +67,7 @@ final class ExtensionSchemaLite extends ExtensionSchema<ExtensionDescriptor> {
@Override
<UT, UB> UB parseExtension(
Object containerMessage,
Reader reader,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
@ -179,6 +179,7 @@ final class ExtensionSchemaLite extends ExtensionSchema<ExtensionDescriptor> {
reader.readEnumList(list);
unknownFields =
SchemaUtil.filterUnknownEnumList(
containerMessage,
fieldNumber,
list,
extension.descriptor.getEnumType(),
@ -200,7 +201,7 @@ final class ExtensionSchemaLite extends ExtensionSchema<ExtensionDescriptor> {
Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number);
if (enumValue == null) {
return SchemaUtil.storeUnknownEnum(
fieldNumber, number, unknownFields, unknownFieldSchema);
containerMessage, fieldNumber, number, unknownFields, unknownFieldSchema);
}
// Note, we store the integer value instead of the actual enum object in FieldSet.
// This is also different from full-runtime where we store EnumValueDescriptor.
@ -528,15 +529,13 @@ final class ExtensionSchemaLite extends ExtensionSchema<ExtensionDescriptor> {
throws IOException {
GeneratedMessageLite.GeneratedExtension<?, ?> extension =
(GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
Object value = extension.getMessageDefaultInstance().newBuilderForType().buildPartial();
Reader reader = BinaryReader.newInstance(ByteBuffer.wrap(data.toByteArray()), true);
MessageLite.Builder builder = extension.getMessageDefaultInstance().newBuilderForType();
Protobuf.getInstance().mergeFrom(value, reader, extensionRegistry);
extensions.setField(extension.descriptor, value);
final CodedInputStream input = data.newCodedInput();
if (reader.getFieldNumber() != Reader.READ_DONE) {
throw InvalidProtocolBufferException.invalidEndTag();
}
builder.mergeFrom(input, extensionRegistry);
extensions.setField(extension.descriptor, builder.buildPartial());
input.checkLastTagWas(0);
}
}

@ -62,11 +62,50 @@ public abstract class GeneratedMessageLite<
BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>>
extends AbstractMessageLite<MessageType, BuilderType> {
/* For use by lite runtime only */
static final int UNINITIALIZED_SERIALIZED_SIZE = 0x7FFFFFFF;
private static final int MUTABLE_FLAG_MASK = 0x80000000;
private static final int MEMOIZED_SERIALIZED_SIZE_MASK = 0x7FFFFFFF;
/**
* We use the high bit of memoizedSerializedSize as the explicit mutability flag. It didn't make
* sense to have negative sizes anyway. Messages start as mutable.
*
* <p>Adding a standalone boolean would have added 8 bytes to every message instance.
*
* <p>We also reserve 0x7FFFFFFF as the "uninitialized" value.
*/
private int memoizedSerializedSize = MUTABLE_FLAG_MASK | UNINITIALIZED_SERIALIZED_SIZE;
/* For use by the runtime only */
static final int UNINITIALIZED_HASH_CODE = 0;
/** For use by generated code only. Lazily initialized to reduce allocations. */
protected UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance();
/** For use by generated code only. */
protected int memoizedSerializedSize = -1;
boolean isMutable() {
return (memoizedSerializedSize & MUTABLE_FLAG_MASK) != 0;
}
void markImmutable() {
memoizedSerializedSize &= ~MUTABLE_FLAG_MASK;
}
int getMemoizedHashCode() {
return memoizedHashCode;
}
void setMemoizedHashCode(int value) {
memoizedHashCode = value;
}
void clearMemoizedHashCode() {
memoizedHashCode = UNINITIALIZED_HASH_CODE;
}
boolean hashCodeIsNotMemoized() {
return UNINITIALIZED_HASH_CODE == getMemoizedHashCode();
}
@Override
@SuppressWarnings("unchecked") // Guaranteed by runtime.
@ -86,6 +125,10 @@ public abstract class GeneratedMessageLite<
return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
}
MessageType newMutableInstance() {
return (MessageType) dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
}
/**
* A reflective toString function. This is primarily intended as a developer aid, while keeping
* binary size down. The first line of the {@code toString()} representation includes a commented
@ -106,11 +149,19 @@ public abstract class GeneratedMessageLite<
@SuppressWarnings("unchecked") // Guaranteed by runtime
@Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
if (isMutable()) {
return computeHashCode();
}
memoizedHashCode = Protobuf.getInstance().schemaFor(this).hashCode(this);
return memoizedHashCode;
if (hashCodeIsNotMemoized()) {
setMemoizedHashCode(computeHashCode());
}
return getMemoizedHashCode();
}
int computeHashCode() {
return Protobuf.getInstance().schemaFor(this).hashCode(this);
}
@SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
@ -173,6 +224,7 @@ public abstract class GeneratedMessageLite<
/** Called by subclasses to complete parsing. For use by generated code only. */
protected void makeImmutable() {
Protobuf.getInstance().schemaFor(this).makeImmutable(this);
markImmutable();
}
protected final <
@ -198,8 +250,7 @@ public abstract class GeneratedMessageLite<
@SuppressWarnings("unchecked")
public final BuilderType toBuilder() {
BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
builder.mergeFrom((MessageType) this);
return builder;
return builder.mergeFrom((MessageType) this);
}
/**
@ -262,14 +313,22 @@ public abstract class GeneratedMessageLite<
return dynamicMethod(method, null, null);
}
void clearMemoizedSerializedSize() {
setMemoizedSerializedSize(UNINITIALIZED_SERIALIZED_SIZE);
}
@Override
int getMemoizedSerializedSize() {
return memoizedSerializedSize;
return memoizedSerializedSize & MEMOIZED_SERIALIZED_SIZE_MASK;
}
@Override
void setMemoizedSerializedSize(int size) {
memoizedSerializedSize = size;
if (size < 0) {
throw new IllegalStateException("serialized size must be non-negative, was " + size);
}
memoizedSerializedSize =
(memoizedSerializedSize & MUTABLE_FLAG_MASK) | (size & MEMOIZED_SERIALIZED_SIZE_MASK);
}
@Override
@ -279,12 +338,42 @@ public abstract class GeneratedMessageLite<
.writeTo(this, CodedOutputStreamWriter.forCodedOutput(output));
}
@Override
int getSerializedSize(Schema schema) {
if (isMutable()) {
// The serialized size should never be memoized for mutable instances.
int size = computeSerializedSize(schema);
if (size < 0) {
throw new IllegalStateException("serialized size must be non-negative, was " + size);
}
return size;
}
// If memoizedSerializedSize has already been set, return it.
if (getMemoizedSerializedSize() != UNINITIALIZED_SERIALIZED_SIZE) {
return getMemoizedSerializedSize();
}
// Need to compute and memoize the serialized size.
int size = computeSerializedSize(schema);
setMemoizedSerializedSize(size);
return size;
}
@Override
public int getSerializedSize() {
if (memoizedSerializedSize == -1) {
memoizedSerializedSize = Protobuf.getInstance().schemaFor(this).getSerializedSize(this);
// Calling this with 'null' to delay schema lookup in case the serializedSize is already
// memoized.
return getSerializedSize(null);
}
private int computeSerializedSize(Schema<?> nullableSchema) {
if (nullableSchema == null) {
return Protobuf.getInstance().schemaFor(this).getSerializedSize(this);
} else {
return ((Schema<GeneratedMessageLite<MessageType, BuilderType>>) nullableSchema)
.getSerializedSize(this);
}
return memoizedSerializedSize;
}
/** Constructs a {@link MessageInfo} for this message type. */
@ -324,6 +413,7 @@ public abstract class GeneratedMessageLite<
protected static <T extends GeneratedMessageLite<?, ?>> void registerDefaultInstance(
Class<T> clazz, T defaultInstance) {
defaultInstanceMap.put(clazz, defaultInstance);
defaultInstance.makeImmutable();
}
protected static Object newMessageInfo(
@ -348,13 +438,19 @@ public abstract class GeneratedMessageLite<
private final MessageType defaultInstance;
protected MessageType instance;
protected boolean isBuilt;
protected Builder(MessageType defaultInstance) {
this.defaultInstance = defaultInstance;
this.instance =
(MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
isBuilt = false;
if (defaultInstance.isMutable()) {
throw new IllegalArgumentException("Default instance must be immutable.");
}
// this.instance should be set to defaultInstance but some tests rely on newBuilder().build()
// creating unique instances.
this.instance = newMutableInstance();
}
private MessageType newMutableInstance() {
return defaultInstance.newMutableInstance();
}
/**
@ -362,15 +458,13 @@ public abstract class GeneratedMessageLite<
* state before the write happens to preserve immutability guarantees.
*/
protected final void copyOnWrite() {
if (isBuilt) {
if (!instance.isMutable()) {
copyOnWriteInternal();
isBuilt = false;
}
}
protected void copyOnWriteInternal() {
MessageType newInstance =
(MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
MessageType newInstance = newMutableInstance();
mergeFromInstance(newInstance, instance);
instance = newInstance;
}
@ -382,27 +476,28 @@ public abstract class GeneratedMessageLite<
@Override
public final BuilderType clear() {
// No need to copy on write since we're dropping the instance anyways.
instance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
// No need to copy on write since we're dropping the instance anyway.
if (defaultInstance.isMutable()) {
throw new IllegalArgumentException("Default instance must be immutable.");
}
instance = newMutableInstance(); // should be defaultInstance;
return (BuilderType) this;
}
@Override
public BuilderType clone() {
BuilderType builder = (BuilderType) getDefaultInstanceForType().newBuilderForType();
builder.mergeFrom(buildPartial());
builder.instance = buildPartial();
return builder;
}
@Override
public MessageType buildPartial() {
if (isBuilt) {
if (!instance.isMutable()) {
return instance;
}
instance.makeImmutable();
isBuilt = true;
return instance;
}
@ -422,12 +517,15 @@ public abstract class GeneratedMessageLite<
/** All subclasses implement this. */
public BuilderType mergeFrom(MessageType message) {
if (getDefaultInstanceForType().equals(message)) {
return (BuilderType) this;
}
copyOnWrite();
mergeFromInstance(instance, message);
return (BuilderType) this;
}
private void mergeFromInstance(MessageType dest, MessageType src) {
private static <MessageType> void mergeFromInstance(MessageType dest, MessageType src) {
Protobuf.getInstance().schemaFor(dest).mergeFrom(dest, src);
}
@ -941,7 +1039,9 @@ public abstract class GeneratedMessageLite<
@Override
protected void copyOnWriteInternal() {
super.copyOnWriteInternal();
instance.extensions = instance.extensions.clone();
if (instance.extensions != FieldSet.emptySet()) {
instance.extensions = instance.extensions.clone();
}
}
private FieldSet<ExtensionDescriptor> ensureExtensionsAreMutable() {
@ -955,7 +1055,7 @@ public abstract class GeneratedMessageLite<
@Override
public final MessageType buildPartial() {
if (isBuilt) {
if (!instance.isMutable()) {
return instance;
}
@ -1538,7 +1638,7 @@ public abstract class GeneratedMessageLite<
T instance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
@SuppressWarnings("unchecked") // Guaranteed by protoc
T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
T result = instance.newMutableInstance();
try {
// TODO(yilunchong): Try to make input with type CodedInpuStream.ArrayDecoder use
// fast path.
@ -1571,15 +1671,12 @@ public abstract class GeneratedMessageLite<
T instance, byte[] input, int offset, int length, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
@SuppressWarnings("unchecked") // Guaranteed by protoc
T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
T result = instance.newMutableInstance();
try {
Schema<T> schema = Protobuf.getInstance().schemaFor(result);
schema.mergeFrom(
result, input, offset, offset + length, new ArrayDecoders.Registers(extensionRegistry));
schema.makeImmutable(result);
if (result.memoizedHashCode != 0) {
throw new RuntimeException();
}
} catch (InvalidProtocolBufferException e) {
if (e.getThrownFromInputStream()) {
e = new InvalidProtocolBufferException(e);

@ -32,12 +32,15 @@ package com.google.protobuf;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.TreeMap;
/** Helps generate {@link String} representations of {@link MessageLite} protos. */
final class MessageLiteToString {
@ -46,6 +49,11 @@ final class MessageLiteToString {
private static final String BUILDER_LIST_SUFFIX = "OrBuilderList";
private static final String MAP_SUFFIX = "Map";
private static final String BYTES_SUFFIX = "Bytes";
private static final char[] INDENT_BUFFER = new char[80];
static {
Arrays.fill(INDENT_BUFFER, ' ');
}
private MessageLiteToString() {
// Classes which are not intended to be instantiated should be made non-instantiable with a
@ -76,37 +84,51 @@ final class MessageLiteToString {
// Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(),
// getFooList() and getFooMap() which might be useful for building an object's string
// representation.
Map<String, Method> nameToNoArgMethod = new HashMap<>();
Map<String, Method> nameToMethod = new HashMap<>();
Set<String> getters = new TreeSet<>();
Set<String> setters = new HashSet<>();
Map<String, Method> hazzers = new HashMap<>();
Map<String, Method> getters = new TreeMap<>();
for (Method method : messageLite.getClass().getDeclaredMethods()) {
nameToMethod.put(method.getName(), method);
if (method.getParameterTypes().length == 0) {
nameToNoArgMethod.put(method.getName(), method);
if (Modifier.isStatic(method.getModifiers())) {
continue;
}
if (method.getName().length() < 3) {
continue;
}
if (method.getName().startsWith("get")) {
getters.add(method.getName());
}
if (method.getName().startsWith("set")) {
setters.add(method.getName());
continue;
}
if (!Modifier.isPublic(method.getModifiers())) {
continue;
}
if (method.getParameterTypes().length != 0) {
continue;
}
if (method.getName().startsWith("has")) {
hazzers.put(method.getName(), method);
} else if (method.getName().startsWith("get")) {
getters.put(method.getName(), method);
}
}
for (String getter : getters) {
String suffix = getter.startsWith("get") ? getter.substring(3) : getter;
for (Entry<String, Method> getter : getters.entrySet()) {
String suffix = getter.getKey().substring(3);
if (suffix.endsWith(LIST_SUFFIX)
&& !suffix.endsWith(BUILDER_LIST_SUFFIX)
// Sometimes people have fields named 'list' that aren't repeated.
&& !suffix.equals(LIST_SUFFIX)) {
String camelCase =
suffix.substring(0, 1).toLowerCase()
+ suffix.substring(1, suffix.length() - LIST_SUFFIX.length());
// Try to reflectively get the value and toString() the field as if it were repeated. This
// only works if the method names have not been proguarded out or renamed.
Method listMethod = nameToNoArgMethod.get(getter);
Method listMethod = getter.getValue();
if (listMethod != null && listMethod.getReturnType().equals(List.class)) {
printField(
buffer,
indent,
camelCaseToSnakeCase(camelCase),
suffix.substring(0, suffix.length() - LIST_SUFFIX.length()),
GeneratedMessageLite.invokeOrDie(listMethod, messageLite));
continue;
}
@ -114,12 +136,9 @@ final class MessageLiteToString {
if (suffix.endsWith(MAP_SUFFIX)
// Sometimes people have fields named 'map' that aren't maps.
&& !suffix.equals(MAP_SUFFIX)) {
String camelCase =
suffix.substring(0, 1).toLowerCase()
+ suffix.substring(1, suffix.length() - MAP_SUFFIX.length());
// Try to reflectively get the value and toString() the field as if it were a map. This only
// works if the method names have not been proguarded out or renamed.
Method mapMethod = nameToNoArgMethod.get(getter);
Method mapMethod = getter.getValue();
if (mapMethod != null
&& mapMethod.getReturnType().equals(Map.class)
// Skip the deprecated getter method with no prefix "Map" when the field name ends with
@ -130,29 +149,25 @@ final class MessageLiteToString {
printField(
buffer,
indent,
camelCaseToSnakeCase(camelCase),
suffix.substring(0, suffix.length() - MAP_SUFFIX.length()),
GeneratedMessageLite.invokeOrDie(mapMethod, messageLite));
continue;
}
}
Method setter = nameToMethod.get("set" + suffix);
if (setter == null) {
if (!setters.contains("set" + suffix)) {
continue;
}
if (suffix.endsWith(BYTES_SUFFIX)
&& nameToNoArgMethod.containsKey(
"get" + suffix.substring(0, suffix.length() - "Bytes".length()))) {
&& getters.containsKey("get" + suffix.substring(0, suffix.length() - "Bytes".length()))) {
// Heuristic to skip bytes based accessors for string fields.
continue;
}
String camelCase = suffix.substring(0, 1).toLowerCase() + suffix.substring(1);
// Try to reflectively get the value and toString() the field as if it were optional. This
// only works if the method names have not been proguarded out or renamed.
Method getMethod = nameToNoArgMethod.get("get" + suffix);
Method hasMethod = nameToNoArgMethod.get("has" + suffix);
Method getMethod = getter.getValue();
Method hasMethod = hazzers.get("has" + suffix);
// TODO(dweis): Fix proto3 semantics.
if (getMethod != null) {
Object value = GeneratedMessageLite.invokeOrDie(getMethod, messageLite);
@ -162,7 +177,7 @@ final class MessageLiteToString {
: (Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite);
// TODO(dweis): This doesn't stop printing oneof case twice: value and enum style.
if (hasValue) {
printField(buffer, indent, camelCaseToSnakeCase(camelCase), value);
printField(buffer, indent, suffix, value);
}
continue;
}
@ -218,10 +233,10 @@ final class MessageLiteToString {
*
* @param buffer the buffer to write to
* @param indent the number of spaces the proto should be indented by
* @param name the field name (in lower underscore case)
* @param name the field name (in PascalCase)
* @param object the object value of the field
*/
static final void printField(StringBuilder buffer, int indent, String name, Object object) {
static void printField(StringBuilder buffer, int indent, String name, Object object) {
if (object instanceof List<?>) {
List<?> list = (List<?>) object;
for (Object entry : list) {
@ -238,10 +253,8 @@ final class MessageLiteToString {
}
buffer.append('\n');
for (int i = 0; i < indent; i++) {
buffer.append(' ');
}
buffer.append(name);
indent(indent, buffer);
buffer.append(pascalCaseToSnakeCase(name));
if (object instanceof String) {
buffer.append(": \"").append(TextFormatEscaper.escapeText((String) object)).append('"');
@ -251,9 +264,7 @@ final class MessageLiteToString {
buffer.append(" {");
reflectivePrintWithIndent((GeneratedMessageLite<?, ?>) object, buffer, indent + 2);
buffer.append("\n");
for (int i = 0; i < indent; i++) {
buffer.append(' ');
}
indent(indent, buffer);
buffer.append("}");
} else if (object instanceof Map.Entry<?, ?>) {
buffer.append(" {");
@ -261,19 +272,33 @@ final class MessageLiteToString {
printField(buffer, indent + 2, "key", entry.getKey());
printField(buffer, indent + 2, "value", entry.getValue());
buffer.append("\n");
for (int i = 0; i < indent; i++) {
buffer.append(' ');
}
indent(indent, buffer);
buffer.append("}");
} else {
buffer.append(": ").append(object);
}
}
private static final String camelCaseToSnakeCase(String camelCase) {
private static void indent(int indent, StringBuilder buffer) {
while (indent > 0) {
int partialIndent = indent;
if (partialIndent > INDENT_BUFFER.length) {
partialIndent = INDENT_BUFFER.length;
}
buffer.append(INDENT_BUFFER, 0, partialIndent);
indent -= partialIndent;
}
}
private static String pascalCaseToSnakeCase(String pascalCase) {
if (pascalCase.isEmpty()) {
return pascalCase;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < camelCase.length(); i++) {
char ch = camelCase.charAt(i);
builder.append(Character.toLowerCase(pascalCase.charAt(0)));
for (int i = 1; i < pascalCase.length(); i++) {
char ch = pascalCase.charAt(i);
if (Character.isUpperCase(ch)) {
builder.append("_");
}

@ -42,7 +42,6 @@ import static com.google.protobuf.ArrayDecoders.decodeFixed64;
import static com.google.protobuf.ArrayDecoders.decodeFixed64List;
import static com.google.protobuf.ArrayDecoders.decodeFloat;
import static com.google.protobuf.ArrayDecoders.decodeFloatList;
import static com.google.protobuf.ArrayDecoders.decodeGroupField;
import static com.google.protobuf.ArrayDecoders.decodeGroupList;
import static com.google.protobuf.ArrayDecoders.decodeMessageField;
import static com.google.protobuf.ArrayDecoders.decodeMessageList;
@ -66,6 +65,8 @@ import static com.google.protobuf.ArrayDecoders.decodeVarint32;
import static com.google.protobuf.ArrayDecoders.decodeVarint32List;
import static com.google.protobuf.ArrayDecoders.decodeVarint64;
import static com.google.protobuf.ArrayDecoders.decodeVarint64List;
import static com.google.protobuf.ArrayDecoders.mergeGroupField;
import static com.google.protobuf.ArrayDecoders.mergeMessageField;
import static com.google.protobuf.ArrayDecoders.skipField;
import com.google.protobuf.ArrayDecoders.Registers;
@ -1177,6 +1178,7 @@ final class MessageSchema<T> implements Schema<T> {
@Override
public void mergeFrom(T message, T other) {
checkMutable(message);
if (other == null) {
throw new NullPointerException();
}
@ -1375,47 +1377,83 @@ final class MessageSchema<T> implements Schema<T> {
}
}
private void mergeMessage(T message, T other, int pos) {
private void mergeMessage(T targetParent, T sourceParent, int pos) {
if (!isFieldPresent(sourceParent, pos)) {
return;
}
final int typeAndOffset = typeAndOffsetAt(pos);
final long offset = offset(typeAndOffset);
if (!isFieldPresent(other, pos)) {
final Object source = UNSAFE.getObject(sourceParent, offset);
if (source == null) {
throw new IllegalStateException(
"Source subfield " + numberAt(pos) + " is present but null: " + sourceParent);
}
final Schema fieldSchema = getMessageFieldSchema(pos);
if (!isFieldPresent(targetParent, pos)) {
if (!isMutable(source)) {
// Can safely share source if it is immutable
UNSAFE.putObject(targetParent, offset, source);
} else {
// Make a safetey copy of source
final Object copyOfSource = fieldSchema.newInstance();
fieldSchema.mergeFrom(copyOfSource, source);
UNSAFE.putObject(targetParent, offset, copyOfSource);
}
setFieldPresent(targetParent, pos);
return;
}
Object mine = UnsafeUtil.getObject(message, offset);
Object theirs = UnsafeUtil.getObject(other, offset);
if (mine != null && theirs != null) {
Object merged = Internal.mergeMessage(mine, theirs);
UnsafeUtil.putObject(message, offset, merged);
setFieldPresent(message, pos);
} else if (theirs != null) {
UnsafeUtil.putObject(message, offset, theirs);
setFieldPresent(message, pos);
// Sub-message is present, merge from source
Object target = UNSAFE.getObject(targetParent, offset);
if (!isMutable(target)) {
Object newInstance = fieldSchema.newInstance();
fieldSchema.mergeFrom(newInstance, target);
UNSAFE.putObject(targetParent, offset, newInstance);
target = newInstance;
}
fieldSchema.mergeFrom(target, source);
}
private void mergeOneofMessage(T message, T other, int pos) {
int typeAndOffset = typeAndOffsetAt(pos);
private void mergeOneofMessage(T targetParent, T sourceParent, int pos) {
int number = numberAt(pos);
long offset = offset(typeAndOffset);
if (!isOneofPresent(other, number, pos)) {
if (!isOneofPresent(sourceParent, number, pos)) {
return;
}
Object mine = null;
if (isOneofPresent(message, number, pos)) {
mine = UnsafeUtil.getObject(message, offset);
long offset = offset(typeAndOffsetAt(pos));
final Object source = UNSAFE.getObject(sourceParent, offset);
if (source == null) {
throw new IllegalStateException(
"Source subfield " + numberAt(pos) + " is present but null: " + sourceParent);
}
Object theirs = UnsafeUtil.getObject(other, offset);
if (mine != null && theirs != null) {
Object merged = Internal.mergeMessage(mine, theirs);
UnsafeUtil.putObject(message, offset, merged);
setOneofPresent(message, number, pos);
} else if (theirs != null) {
UnsafeUtil.putObject(message, offset, theirs);
setOneofPresent(message, number, pos);
final Schema fieldSchema = getMessageFieldSchema(pos);
if (!isOneofPresent(targetParent, number, pos)) {
if (!isMutable(source)) {
// Can safely share source if it is immutable
UNSAFE.putObject(targetParent, offset, source);
} else {
// Make a safety copy of theirs
final Object copyOfSource = fieldSchema.newInstance();
fieldSchema.mergeFrom(copyOfSource, source);
UNSAFE.putObject(targetParent, offset, copyOfSource);
}
setOneofPresent(targetParent, number, pos);
return;
}
// Sub-message is present, merge from source
Object target = UNSAFE.getObject(targetParent, offset);
if (!isMutable(target)) {
Object newInstance = fieldSchema.newInstance();
fieldSchema.mergeFrom(newInstance, target);
UNSAFE.putObject(targetParent, offset, newInstance);
target = newInstance;
}
fieldSchema.mergeFrom(target, source);
}
@Override
@ -3853,6 +3891,7 @@ final class MessageSchema<T> implements Schema<T> {
if (extensionRegistry == null) {
throw new NullPointerException();
}
checkMutable(message);
mergeFromHelper(unknownFieldSchema, extensionSchema, message, reader, extensionRegistry);
}
@ -3889,6 +3928,7 @@ final class MessageSchema<T> implements Schema<T> {
}
unknownFields =
extensionSchema.parseExtension(
message,
reader,
extension,
extensionRegistry,
@ -3955,21 +3995,10 @@ final class MessageSchema<T> implements Schema<T> {
break;
case 9:
{ // MESSAGE:
if (isFieldPresent(message, pos)) {
Object mergedResult =
Internal.mergeMessage(
UnsafeUtil.getObject(message, offset(typeAndOffset)),
reader.readMessageBySchemaWithCheck(
(Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
} else {
UnsafeUtil.putObject(
message,
offset(typeAndOffset),
reader.readMessageBySchemaWithCheck(
(Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
setFieldPresent(message, pos);
}
final MessageLite current = (MessageLite) mutableMessageFieldForMerge(message, pos);
reader.mergeMessageField(
current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry);
storeMessageField(message, pos, current);
break;
}
case 10: // BYTES:
@ -3990,7 +4019,7 @@ final class MessageSchema<T> implements Schema<T> {
} else {
unknownFields =
SchemaUtil.storeUnknownEnum(
number, enumValue, unknownFields, unknownFieldSchema);
message, number, enumValue, unknownFields, unknownFieldSchema);
}
break;
}
@ -4012,21 +4041,10 @@ final class MessageSchema<T> implements Schema<T> {
break;
case 17:
{ // GROUP:
if (isFieldPresent(message, pos)) {
Object mergedResult =
Internal.mergeMessage(
UnsafeUtil.getObject(message, offset(typeAndOffset)),
reader.readGroupBySchemaWithCheck(
(Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
} else {
UnsafeUtil.putObject(
message,
offset(typeAndOffset),
reader.readGroupBySchemaWithCheck(
(Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
setFieldPresent(message, pos);
}
final MessageLite current = (MessageLite) mutableMessageFieldForMerge(message, pos);
reader.mergeGroupField(
current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry);
storeMessageField(message, pos, current);
break;
}
case 18: // DOUBLE_LIST:
@ -4089,6 +4107,7 @@ final class MessageSchema<T> implements Schema<T> {
reader.readEnumList(enumList);
unknownFields =
SchemaUtil.filterUnknownEnumList(
message,
number,
enumList,
getEnumFieldVerifier(pos),
@ -4155,6 +4174,7 @@ final class MessageSchema<T> implements Schema<T> {
reader.readEnumList(enumList);
unknownFields =
SchemaUtil.filterUnknownEnumList(
message,
number,
enumList,
getEnumFieldVerifier(pos),
@ -4235,24 +4255,15 @@ final class MessageSchema<T> implements Schema<T> {
readString(message, typeAndOffset, reader);
setOneofPresent(message, number, pos);
break;
case 60: // ONEOF_MESSAGE:
if (isOneofPresent(message, number, pos)) {
Object mergedResult =
Internal.mergeMessage(
UnsafeUtil.getObject(message, offset(typeAndOffset)),
reader.readMessageBySchemaWithCheck(
getMessageFieldSchema(pos), extensionRegistry));
UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
} else {
UnsafeUtil.putObject(
message,
offset(typeAndOffset),
reader.readMessageBySchemaWithCheck(
getMessageFieldSchema(pos), extensionRegistry));
setFieldPresent(message, pos);
case 60:
{ // ONEOF_MESSAGE:
final MessageLite current =
(MessageLite) mutableOneofMessageFieldForMerge(message, number, pos);
reader.mergeMessageField(
current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry);
storeOneofMessageField(message, number, pos, current);
break;
}
setOneofPresent(message, number, pos);
break;
case 61: // ONEOF_BYTES:
UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes());
setOneofPresent(message, number, pos);
@ -4272,7 +4283,7 @@ final class MessageSchema<T> implements Schema<T> {
} else {
unknownFields =
SchemaUtil.storeUnknownEnum(
number, enumValue, unknownFields, unknownFieldSchema);
message, number, enumValue, unknownFields, unknownFieldSchema);
}
break;
}
@ -4296,17 +4307,19 @@ final class MessageSchema<T> implements Schema<T> {
message, offset(typeAndOffset), Long.valueOf(reader.readSInt64()));
setOneofPresent(message, number, pos);
break;
case 68: // ONEOF_GROUP:
UnsafeUtil.putObject(
message,
offset(typeAndOffset),
reader.readGroupBySchemaWithCheck(getMessageFieldSchema(pos), extensionRegistry));
setOneofPresent(message, number, pos);
break;
case 68:
{ // ONEOF_GROUP:
final MessageLite current =
(MessageLite) mutableOneofMessageFieldForMerge(message, number, pos);
reader.mergeGroupField(
current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry);
storeOneofMessageField(message, number, pos, current);
break;
}
default:
// Assume we've landed on an empty entry. Treat it as an unknown field.
if (unknownFields == null) {
unknownFields = unknownFieldSchema.newBuilder();
unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
}
if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
return;
@ -4333,7 +4346,8 @@ final class MessageSchema<T> implements Schema<T> {
} finally {
for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
unknownFields =
filterMapUnknownEnumValues(message, intArray[i], unknownFields, unknownFieldSchema);
filterMapUnknownEnumValues(
message, intArray[i], unknownFields, unknownFieldSchema, message);
}
if (unknownFields != null) {
unknownFieldSchema.setBuilderToMessage(message, unknownFields);
@ -4343,6 +4357,8 @@ final class MessageSchema<T> implements Schema<T> {
@SuppressWarnings("ReferenceEquality")
static UnknownFieldSetLite getMutableUnknownFields(Object message) {
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
// better.
UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
@ -4603,24 +4619,13 @@ final class MessageSchema<T> implements Schema<T> {
} else {
break;
}
UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
// filterUnknownEnumList() expects the unknownFields parameter to be mutable or null.
// Since we don't know yet whether there exist unknown enum values, we'd better pass
// null to it instead of allocating a mutable instance. This is also needed to be
// consistent with the behavior of generated parser/builder.
unknownFields = null;
}
unknownFields =
SchemaUtil.filterUnknownEnumList(
number,
(ProtobufList<Integer>) list,
getEnumFieldVerifier(bufferPosition),
unknownFields,
(UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema);
if (unknownFields != null) {
((GeneratedMessageLite) message).unknownFields = unknownFields;
}
SchemaUtil.filterUnknownEnumList(
message,
number,
(ProtobufList<Integer>) list,
getEnumFieldVerifier(bufferPosition),
null,
(UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema);
break;
case 33: // SINT32_LIST:
case 47: // SINT32_LIST_PACKED:
@ -4774,20 +4779,11 @@ final class MessageSchema<T> implements Schema<T> {
break;
case 60: // ONEOF_MESSAGE:
if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
final Object current = mutableOneofMessageFieldForMerge(message, number, bufferPosition);
position =
decodeMessageField(
getMessageFieldSchema(bufferPosition), data, position, limit, registers);
final Object oldValue =
unsafe.getInt(message, oneofCaseOffset) == number
? unsafe.getObject(message, fieldOffset)
: null;
if (oldValue == null) {
unsafe.putObject(message, fieldOffset, registers.object1);
} else {
unsafe.putObject(
message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
}
unsafe.putInt(message, oneofCaseOffset, number);
mergeMessageField(
current, getMessageFieldSchema(bufferPosition), data, position, limit, registers);
storeOneofMessageField(message, number, bufferPosition, current);
}
break;
case 61: // ONEOF_BYTES:
@ -4827,21 +4823,18 @@ final class MessageSchema<T> implements Schema<T> {
break;
case 68: // ONEOF_GROUP:
if (wireType == WireFormat.WIRETYPE_START_GROUP) {
final Object current = mutableOneofMessageFieldForMerge(message, number, bufferPosition);
final int endTag = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP;
position =
decodeGroupField(
getMessageFieldSchema(bufferPosition), data, position, limit, endTag, registers);
final Object oldValue =
unsafe.getInt(message, oneofCaseOffset) == number
? unsafe.getObject(message, fieldOffset)
: null;
if (oldValue == null) {
unsafe.putObject(message, fieldOffset, registers.object1);
} else {
unsafe.putObject(
message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
}
unsafe.putInt(message, oneofCaseOffset, number);
mergeGroupField(
current,
getMessageFieldSchema(bufferPosition),
data,
position,
limit,
endTag,
registers);
storeOneofMessageField(message, number, bufferPosition, current);
}
break;
default:
@ -4879,6 +4872,7 @@ final class MessageSchema<T> implements Schema<T> {
int parseProto2Message(
T message, byte[] data, int position, int limit, int endGroup, Registers registers)
throws IOException {
checkMutable(message);
final sun.misc.Unsafe unsafe = UNSAFE;
int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
int currentPresenceField = 0;
@ -4995,18 +4989,11 @@ final class MessageSchema<T> implements Schema<T> {
break;
case 9: // MESSAGE
if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
final Object current = mutableMessageFieldForMerge(message, pos);
position =
decodeMessageField(
getMessageFieldSchema(pos), data, position, limit, registers);
if ((currentPresenceField & presenceMask) == 0) {
unsafe.putObject(message, fieldOffset, registers.object1);
} else {
unsafe.putObject(
message,
fieldOffset,
Internal.mergeMessage(
unsafe.getObject(message, fieldOffset), registers.object1));
}
mergeMessageField(
current, getMessageFieldSchema(pos), data, position, limit, registers);
storeMessageField(message, pos, current);
currentPresenceField |= presenceMask;
continue;
}
@ -5055,20 +5042,18 @@ final class MessageSchema<T> implements Schema<T> {
break;
case 17: // GROUP
if (wireType == WireFormat.WIRETYPE_START_GROUP) {
final Object current = mutableMessageFieldForMerge(message, pos);
final int endTag = (number << 3) | WireFormat.WIRETYPE_END_GROUP;
position =
decodeGroupField(
getMessageFieldSchema(pos), data, position, limit, endTag, registers);
if ((currentPresenceField & presenceMask) == 0) {
unsafe.putObject(message, fieldOffset, registers.object1);
} else {
unsafe.putObject(
message,
fieldOffset,
Internal.mergeMessage(
unsafe.getObject(message, fieldOffset), registers.object1));
}
mergeGroupField(
current,
getMessageFieldSchema(pos),
data,
position,
limit,
endTag,
registers);
storeMessageField(message, pos, current);
currentPresenceField |= presenceMask;
continue;
}
@ -5166,7 +5151,8 @@ final class MessageSchema<T> implements Schema<T> {
message,
intArray[i],
unknownFields,
(UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema);
(UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema,
message);
}
if (unknownFields != null) {
((UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema)
@ -5184,10 +5170,66 @@ final class MessageSchema<T> implements Schema<T> {
return position;
}
private Object mutableMessageFieldForMerge(T message, int pos) {
final Schema fieldSchema = getMessageFieldSchema(pos);
final long offset = offset(typeAndOffsetAt(pos));
// Field not present, create a new one
if (!isFieldPresent(message, pos)) {
return fieldSchema.newInstance();
}
// Field present, if mutable, ready to merge
final Object current = UNSAFE.getObject(message, offset);
if (isMutable(current)) {
return current;
}
// Field present but immutable, make a new mutable copy
final Object newMessage = fieldSchema.newInstance();
if (current != null) {
fieldSchema.mergeFrom(newMessage, current);
}
return newMessage;
}
private void storeMessageField(T message, int pos, Object field) {
UNSAFE.putObject(message, offset(typeAndOffsetAt(pos)), field);
setFieldPresent(message, pos);
}
private Object mutableOneofMessageFieldForMerge(T message, int fieldNumber, int pos) {
final Schema fieldSchema = getMessageFieldSchema(pos);
// Field not present, create it and mark it present
if (!isOneofPresent(message, fieldNumber, pos)) {
return fieldSchema.newInstance();
}
// Field present, if mutable, ready to merge
final Object current = UNSAFE.getObject(message, offset(typeAndOffsetAt(pos)));
if (isMutable(current)) {
return current;
}
// Field present but immutable, make a new mutable copy
final Object newMessage = fieldSchema.newInstance();
if (current != null) {
fieldSchema.mergeFrom(newMessage, current);
}
return newMessage;
}
private void storeOneofMessageField(T message, int fieldNumber, int pos, Object field) {
UNSAFE.putObject(message, offset(typeAndOffsetAt(pos)), field);
setOneofPresent(message, fieldNumber, pos);
}
/** Parses a proto3 message and returns the limit if parsing is successful. */
@CanIgnoreReturnValue
private int parseProto3Message(
T message, byte[] data, int position, int limit, Registers registers) throws IOException {
checkMutable(message);
final sun.misc.Unsafe unsafe = UNSAFE;
int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
int currentPresenceField = 0;
@ -5309,16 +5351,11 @@ final class MessageSchema<T> implements Schema<T> {
break;
case 9: // MESSAGE:
if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
final Object current = mutableMessageFieldForMerge(message, pos);
position =
decodeMessageField(
getMessageFieldSchema(pos), data, position, limit, registers);
final Object oldValue = unsafe.getObject(message, fieldOffset);
if (oldValue == null) {
unsafe.putObject(message, fieldOffset, registers.object1);
} else {
unsafe.putObject(
message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
}
mergeMessageField(
current, getMessageFieldSchema(pos), data, position, limit, registers);
storeMessageField(message, pos, current);
currentPresenceField |= presenceMask;
continue;
}
@ -5449,18 +5486,73 @@ final class MessageSchema<T> implements Schema<T> {
@Override
public void makeImmutable(T message) {
// Make all repeated/map fields immutable.
for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
long offset = offset(typeAndOffsetAt(intArray[i]));
Object mapField = UnsafeUtil.getObject(message, offset);
if (mapField == null) {
continue;
}
UnsafeUtil.putObject(message, offset, mapFieldSchema.toImmutable(mapField));
if (!isMutable(message)) {
return;
}
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
// better.
if (message instanceof GeneratedMessageLite) {
GeneratedMessageLite<?, ?> generatedMessage = ((GeneratedMessageLite<?, ?>) message);
generatedMessage.clearMemoizedSerializedSize();
generatedMessage.clearMemoizedHashCode();
generatedMessage.markImmutable();
}
final int length = intArray.length;
for (int i = repeatedFieldOffsetStart; i < length; i++) {
listFieldSchema.makeImmutableListAt(message, intArray[i]);
final int bufferLength = buffer.length;
for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
final int typeAndOffset = typeAndOffsetAt(pos);
final long offset = offset(typeAndOffset);
switch (type(typeAndOffset)) {
case 17: // GROUP
case 9: // MESSAGE
if (isFieldPresent(message, pos)) {
getMessageFieldSchema(pos).makeImmutable(UNSAFE.getObject(message, offset));
}
break;
case 18: // DOUBLE_LIST:
case 19: // FLOAT_LIST:
case 20: // INT64_LIST:
case 21: // UINT64_LIST:
case 22: // INT32_LIST:
case 23: // FIXED64_LIST:
case 24: // FIXED32_LIST:
case 25: // BOOL_LIST:
case 26: // STRING_LIST:
case 27: // MESSAGE_LIST:
case 28: // BYTES_LIST:
case 29: // UINT32_LIST:
case 30: // ENUM_LIST:
case 31: // SFIXED32_LIST:
case 32: // SFIXED64_LIST:
case 33: // SINT32_LIST:
case 34: // SINT64_LIST:
case 35: // DOUBLE_LIST_PACKED:
case 36: // FLOAT_LIST_PACKED:
case 37: // INT64_LIST_PACKED:
case 38: // UINT64_LIST_PACKED:
case 39: // INT32_LIST_PACKED:
case 40: // FIXED64_LIST_PACKED:
case 41: // FIXED32_LIST_PACKED:
case 42: // BOOL_LIST_PACKED:
case 43: // UINT32_LIST_PACKED:
case 44: // ENUM_LIST_PACKED:
case 45: // SFIXED32_LIST_PACKED:
case 46: // SFIXED64_LIST_PACKED:
case 47: // SINT32_LIST_PACKED:
case 48: // SINT64_LIST_PACKED:
case 49: // GROUP_LIST:
listFieldSchema.makeImmutableListAt(message, offset);
break;
case 50: // MAP:
{
Object mapField = UNSAFE.getObject(message, offset);
if (mapField != null) {
UNSAFE.putObject(message, offset, mapFieldSchema.toImmutable(mapField));
}
}
break;
}
}
unknownFieldSchema.makeImmutable(message);
if (hasExtensions) {
@ -5497,8 +5589,12 @@ final class MessageSchema<T> implements Schema<T> {
extensionRegistry);
}
private final <UT, UB> UB filterMapUnknownEnumValues(
Object message, int pos, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
private <UT, UB> UB filterMapUnknownEnumValues(
Object message,
int pos,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema,
Object containerMessage) {
int fieldNumber = numberAt(pos);
long offset = offset(typeAndOffsetAt(pos));
Object mapField = UnsafeUtil.getObject(message, offset);
@ -5513,25 +5609,32 @@ final class MessageSchema<T> implements Schema<T> {
// Filter unknown enum values.
unknownFields =
filterUnknownEnumMap(
pos, fieldNumber, mapData, enumVerifier, unknownFields, unknownFieldSchema);
pos,
fieldNumber,
mapData,
enumVerifier,
unknownFields,
unknownFieldSchema,
containerMessage);
return unknownFields;
}
@SuppressWarnings("unchecked")
private final <K, V, UT, UB> UB filterUnknownEnumMap(
private <K, V, UT, UB> UB filterUnknownEnumMap(
int pos,
int number,
Map<K, V> mapData,
EnumVerifier enumVerifier,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema) {
UnknownFieldSchema<UT, UB> unknownFieldSchema,
Object containerMessage) {
Metadata<K, V> metadata =
(Metadata<K, V>) mapFieldSchema.forMapMetadata(getMapFieldDefaultEntry(pos));
for (Iterator<Map.Entry<K, V>> it = mapData.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<K, V> entry = it.next();
if (!enumVerifier.isInRange((Integer) entry.getValue())) {
if (unknownFields == null) {
unknownFields = unknownFieldSchema.newBuilder();
unknownFields = unknownFieldSchema.getBuilderFromMessage(containerMessage);
}
int entrySize =
MapEntryLite.computeSerializedSize(metadata, entry.getKey(), entry.getValue());
@ -5748,6 +5851,28 @@ final class MessageSchema<T> implements Schema<T> {
return value & OFFSET_MASK;
}
private static boolean isMutable(Object message) {
if (message == null) {
return false;
}
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
// better.
if (message instanceof GeneratedMessageLite<?, ?>) {
return ((GeneratedMessageLite<?, ?>) message).isMutable();
}
// For other types, we'll assume this is true because that's what was
// happening before we started checking.
return true;
}
private static void checkMutable(Object message) {
if (!isMutable(message)) {
throw new IllegalArgumentException("Mutating immutable message: " + message);
}
}
private static <T> double doubleAt(T message, long offset) {
return UnsafeUtil.getDouble(message, offset);
}

@ -62,7 +62,13 @@ final class MessageSetSchema<T> implements Schema<T> {
@SuppressWarnings("unchecked")
@Override
public T newInstance() {
return (T) defaultInstance.newBuilderForType().buildPartial();
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
// better.
if (defaultInstance instanceof GeneratedMessageLite) {
return (T) ((GeneratedMessageLite<?, ?>) defaultInstance).newMutableInstance();
} else {
return (T) defaultInstance.newBuilderForType().buildPartial();
}
}
@Override
@ -133,6 +139,8 @@ final class MessageSetSchema<T> implements Schema<T> {
public void mergeFrom(
T message, byte[] data, int position, int limit, ArrayDecoders.Registers registers)
throws IOException {
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
// better.
UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
@ -181,9 +189,12 @@ final class MessageSetSchema<T> implements Schema<T> {
if (wireType == WireFormat.WIRETYPE_VARINT) {
position = ArrayDecoders.decodeVarint32(data, position, registers);
typeId = registers.int1;
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and
// handle this better.
extension =
(GeneratedMessageLite.GeneratedExtension<?, ?>) extensionSchema
.findExtensionByNumber(registers.extensionRegistry, defaultInstance, typeId);
(GeneratedMessageLite.GeneratedExtension<?, ?>)
extensionSchema.findExtensionByNumber(
registers.extensionRegistry, defaultInstance, typeId);
continue;
}
break;

@ -34,7 +34,8 @@ package com.google.protobuf;
final class NewInstanceSchemaLite implements NewInstanceSchema {
@Override
public Object newInstance(Object defaultInstance) {
return ((GeneratedMessageLite) defaultInstance)
.dynamicMethod(GeneratedMessageLite.MethodToInvoke.NEW_MUTABLE_INSTANCE);
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
// better.
return ((GeneratedMessageLite<?, ?>) defaultInstance).newMutableInstance();
}
}

@ -159,6 +159,14 @@ interface Reader {
<T> T readGroupBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException;
/** Read a message field from the wire format and merge the results into the given target. */
<T> void mergeMessageField(T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException;
/** Read a group field from the wire format and merge the results into the given target. */
<T> void mergeGroupField(T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException;
/**
* Reads and returns the next field of type {@code BYTES} and advances the reader to the next
* field.

@ -60,6 +60,8 @@ final class SchemaUtil {
* GeneratedMessageLite}.
*/
public static void requireGeneratedMessage(Class<?> messageType) {
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
// better.
if (!GeneratedMessageLite.class.isAssignableFrom(messageType)
&& GENERATED_MESSAGE_CLASS != null
&& !GENERATED_MESSAGE_CLASS.isAssignableFrom(messageType)) {
@ -809,6 +811,8 @@ final class SchemaUtil {
private static Class<?> getGeneratedMessageClass() {
try {
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle
// this better.
return Class.forName("com.google.protobuf.GeneratedMessageV3");
} catch (Throwable e) {
return null;
@ -901,7 +905,9 @@ final class SchemaUtil {
}
/** Filters unrecognized enum values in a list. */
@CanIgnoreReturnValue
static <UT, UB> UB filterUnknownEnumList(
Object containerMessage,
int number,
List<Integer> enumList,
EnumLiteMap<?> enumMap,
@ -922,7 +928,9 @@ final class SchemaUtil {
}
++writePos;
} else {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
unknownFields =
storeUnknownEnum(
containerMessage, number, enumValue, unknownFields, unknownFieldSchema);
}
}
if (writePos != size) {
@ -932,7 +940,9 @@ final class SchemaUtil {
for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
int enumValue = it.next();
if (enumMap.findValueByNumber(enumValue) == null) {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
unknownFields =
storeUnknownEnum(
containerMessage, number, enumValue, unknownFields, unknownFieldSchema);
it.remove();
}
}
@ -941,7 +951,9 @@ final class SchemaUtil {
}
/** Filters unrecognized enum values in a list. */
@CanIgnoreReturnValue
static <UT, UB> UB filterUnknownEnumList(
Object containerMessage,
int number,
List<Integer> enumList,
EnumVerifier enumVerifier,
@ -962,7 +974,9 @@ final class SchemaUtil {
}
++writePos;
} else {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
unknownFields =
storeUnknownEnum(
containerMessage, number, enumValue, unknownFields, unknownFieldSchema);
}
}
if (writePos != size) {
@ -972,7 +986,9 @@ final class SchemaUtil {
for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
int enumValue = it.next();
if (!enumVerifier.isInRange(enumValue)) {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
unknownFields =
storeUnknownEnum(
containerMessage, number, enumValue, unknownFields, unknownFieldSchema);
it.remove();
}
}
@ -983,9 +999,13 @@ final class SchemaUtil {
/** Stores an unrecognized enum value as an unknown value. */
@CanIgnoreReturnValue
static <UT, UB> UB storeUnknownEnum(
int number, int enumValue, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
Object containerMessage,
int number,
int enumValue,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema) {
if (unknownFields == null) {
unknownFields = unknownFieldSchema.newBuilder();
unknownFields = unknownFieldSchema.getBuilderFromMessage(containerMessage);
}
unknownFieldSchema.addVarint(unknownFields, number, enumValue);
return unknownFields;

@ -388,7 +388,7 @@ public final class UnknownFieldSetLite {
// Package private for unsafe experimental runtime.
void storeField(int tag, Object value) {
checkMutable();
ensureCapacity();
ensureCapacity(count + 1);
tags[count] = tag;
objects[count] = value;
@ -396,13 +396,23 @@ public final class UnknownFieldSetLite {
}
/** Ensures that our arrays are long enough to store more metadata. */
private void ensureCapacity() {
if (count == tags.length) {
int increment = count < (MIN_CAPACITY / 2) ? MIN_CAPACITY : count >> 1;
int newLength = count + increment;
private void ensureCapacity(int minCapacity) {
if (minCapacity > this.tags.length) {
// Increase by at least 50%
int newCapacity = count + count / 2;
// Or new capacity if higher
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
// And never less than MIN_CAPACITY
if (newCapacity < MIN_CAPACITY) {
newCapacity = MIN_CAPACITY;
}
tags = Arrays.copyOf(tags, newLength);
objects = Arrays.copyOf(objects, newLength);
this.tags = Arrays.copyOf(this.tags, newCapacity);
this.objects = Arrays.copyOf(this.objects, newCapacity);
}
}
@ -487,4 +497,19 @@ public final class UnknownFieldSetLite {
}
return this;
}
@CanIgnoreReturnValue
UnknownFieldSetLite mergeFrom(UnknownFieldSetLite other) {
if (other.equals(getDefaultInstance())) {
return this;
}
checkMutable();
int newCount = this.count + other.count;
ensureCapacity(newCount);
System.arraycopy(other.tags, 0, tags, this.count, other.count);
System.arraycopy(other.objects, 0, objects, this.count, other.count);
this.count = newCount;
return this;
}
}

@ -123,10 +123,14 @@ class UnknownFieldSetLiteSchema
}
@Override
UnknownFieldSetLite merge(UnknownFieldSetLite message, UnknownFieldSetLite other) {
return other.equals(UnknownFieldSetLite.getDefaultInstance())
? message
: UnknownFieldSetLite.mutableCopyOf(message, other);
UnknownFieldSetLite merge(UnknownFieldSetLite target, UnknownFieldSetLite source) {
if (UnknownFieldSetLite.getDefaultInstance().equals(source)) {
return target;
}
if (UnknownFieldSetLite.getDefaultInstance().equals(target)) {
return UnknownFieldSetLite.mutableCopyOf(target, source);
}
return target.mergeFrom(source);
}
@Override

@ -192,19 +192,28 @@ public class LiteTest {
@Test
public void testMemoization() throws Exception {
TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet();
GeneratedMessageLite<?, ?> message = TestUtilLite.getAllLiteExtensionsSet();
// This built message should not be mutable
assertThat(message.isMutable()).isFalse();
// Test serialized size is memoized
message.memoizedSerializedSize = -1;
assertThat(message.getMemoizedSerializedSize())
.isEqualTo(GeneratedMessageLite.UNINITIALIZED_SERIALIZED_SIZE);
int size = message.getSerializedSize();
assertThat(size).isGreaterThan(0);
assertThat(message.memoizedSerializedSize).isEqualTo(size);
assertThat(message.getMemoizedSerializedSize()).isEqualTo(size);
message.clearMemoizedSerializedSize();
assertThat(message.getMemoizedSerializedSize())
.isEqualTo(GeneratedMessageLite.UNINITIALIZED_SERIALIZED_SIZE);
// Test hashCode is memoized
assertThat(message.memoizedHashCode).isEqualTo(0);
assertThat(message.hashCodeIsNotMemoized()).isTrue();
int hashCode = message.hashCode();
assertThat(hashCode).isNotEqualTo(0);
assertThat(hashCode).isEqualTo(message.memoizedHashCode);
assertThat(message.hashCodeIsNotMemoized()).isFalse();
assertThat(message.getMemoizedHashCode()).isEqualTo(hashCode);
message.clearMemoizedHashCode();
assertThat(message.hashCodeIsNotMemoized()).isTrue();
// Test isInitialized is memoized
Field memo = message.getClass().getDeclaredField("memoizedIsInitialized");

@ -8,7 +8,7 @@
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<version>3.21.3</version>
<version>3.21.6</version>
<packaging>pom</packaging>
<name>Protobuf Compiler</name>
<description>

@ -40,8 +40,8 @@ mkdir -p protoc/linux_x86
mkdir -p protoc/linux_x64
# Because of maven unrelated reasonse the linux protoc binaries have a dummy .exe extension.
# For the Google.Protobuf.Tools nuget, we don't want that exception, so we just remove it.
cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_32/protoc.exe protoc/linux_x86/protoc
cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_64/protoc.exe protoc/linux_x64/protoc
cp ${INPUT_ARTIFACTS_DIR}/kokoro/release/protoc/target/linux/x86_32/protoc.exe protoc/linux_x86/protoc
cp ${INPUT_ARTIFACTS_DIR}/kokoro/release/protoc/target/linux/x86_64/protoc.exe protoc/linux_x64/protoc
mkdir -p protoc/macosx_x64
cp ${INPUT_ARTIFACTS_DIR}/build64/src/protoc protoc/macosx_x64/protoc

@ -18,12 +18,12 @@ git submodule update --init --recursive
# directories afterward.
protoc-artifacts/build-protoc.sh linux aarch_64 protoc
kokoro/release/protoc/build-protoc.sh linux aarch_64 protoc
protoc-artifacts/build-protoc.sh linux ppcle_64 protoc
kokoro/release/protoc/build-protoc.sh linux ppcle_64 protoc
protoc-artifacts/build-protoc.sh linux s390_64 protoc
kokoro/release/protoc/build-protoc.sh linux s390_64 protoc
protoc-artifacts/build-protoc.sh linux x86_64 protoc
kokoro/release/protoc/build-protoc.sh linux x86_64 protoc
protoc-artifacts/build-protoc.sh linux x86_32 protoc
kokoro/release/protoc/build-protoc.sh linux x86_32 protoc

@ -1,34 +0,0 @@
@rem enter repo root
cd /d %~dp0\..\..\..
call kokoro\windows\prepare_build_win64.bat || goto :error
@rem TODO(b/241475022) Use docker to guarantee better stability.
@rem TODO(b/241484899) Run conformance tests in windows.
md build
md %KOKORO_ARTIFACTS_DIR%\logs
cd build
cmake .. ^
-G "NMake Makefiles" ^
-DCMAKE_C_COMPILER=cl.exe ^
-DCMAKE_CXX_COMPILER=cl.exe ^
-Dprotobuf_BUILD_CONFORMANCE=OFF ^
-Dprotobuf_WITH_ZLIB=OFF ^
-Dprotobuf_TEST_XML_OUTDIR=%KOKORO_ARTIFACTS_DIR%\logs\ || goto :error
cmake --build . || goto :error
ctest --verbose -C Debug || goto :error
goto :success
:error
cd /d %~dp0\..\..\..
echo Failed!
exit /b 1
:success
cd ..

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

@ -1 +0,0 @@
# Keep this file empty! Use common.cfg instead.

@ -1 +0,0 @@
# Keep this file empty! Use common.cfg instead.

@ -224,20 +224,11 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
# just pick a mix of OS Versions and 32/64 bit.
# NOTE: Different Xcode have different simulated hardware/os support.
case "${XCODE_VERSION}" in
[6-9].* )
echo "ERROR: Xcode 10.2 or higher is required." 1>&2
[6-9].* | 1[0-2].* )
echo "ERROR: Xcode 13.3.1 or higher is required." 1>&2
exit 11
;;
10.*)
XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
-destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
# 10.x also seems to often fail running destinations in parallel (with
# 32bit one include at least)
-disable-concurrent-destination-testing
)
;;
11.* | 12.* | 13.* | 14.*)
13.* | 14.*)
# Dropped 32bit as Apple doesn't seem support the simulators either.
XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit
@ -274,8 +265,8 @@ if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
XCODEBUILD_TEST_BASE_OSX+=( -quiet )
fi
case "${XCODE_VERSION}" in
[6-9].* )
echo "ERROR: Xcode 10.2 or higher is required." 1>&2
[6-9].* | 1[0-2].* )
echo "ERROR: Xcode 13.3.1 or higher is required." 1>&2
exit 11
;;
esac
@ -295,15 +286,10 @@ if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then
-scheme ProtocolBuffers
)
case "${XCODE_VERSION}" in
[6-9].* )
echo "ERROR: Xcode 10.2 or higher is required." 1>&2
[6-9].* | 1[0-2].* )
echo "ERROR: Xcode 13.3.1 or higher is required." 1>&2
exit 11
;;
10.* | 11.* | 12.*)
XCODEBUILD_TEST_BASE_TVOS+=(
-destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest"
)
;;
13.* | 14.*)
XCODEBUILD_TEST_BASE_TVOS+=(
-destination "platform=tvOS Simulator,name=Apple TV 4K (2nd generation),OS=latest"

@ -416,19 +416,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
//% if (tag != 0) {
//% if (values.count == 0) return;
//% __block size_t dataSize = 0;
//% [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
//%#pragma unused(idx, stop)
//% [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, __unused NSUInteger idx,__unused BOOL *stop) {
//% dataSize += GPBCompute##NAME##SizeNoTag(value);
//% }];
//% GPBWriteRawVarint32(&state_, tag);
//% GPBWriteRawVarint32(&state_, (int32_t)dataSize);
//% [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
//%#pragma unused(idx, stop)
//% [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, __unused NSUInteger idx, __unused BOOL *stop) {
//% [self write##NAME##NoTag:value];
//% }];
//% } else {
//% [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
//%#pragma unused(idx, stop)
//% [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, __unused NSUInteger idx, __unused BOOL *stop) {
//% [self write##NAME:fieldNumber value:value];
//% }];
//% }
@ -450,19 +447,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(double value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeDoubleSizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(double value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeDoubleNoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(double value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeDouble:fieldNumber value:value];
}];
}
@ -477,19 +471,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(float value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeFloatSizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(float value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeFloatNoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(float value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeFloat:fieldNumber value:value];
}];
}
@ -504,19 +495,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeUInt64SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeUInt64NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeUInt64:fieldNumber value:value];
}];
}
@ -531,19 +519,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeInt64SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeInt64NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeInt64:fieldNumber value:value];
}];
}
@ -558,19 +543,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeInt32SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeInt32NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeInt32:fieldNumber value:value];
}];
}
@ -585,19 +567,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeUInt32SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeUInt32NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeUInt32:fieldNumber value:value];
}];
}
@ -612,19 +591,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeFixed64SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeFixed64NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeFixed64:fieldNumber value:value];
}];
}
@ -639,19 +615,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeFixed32SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeFixed32NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeFixed32:fieldNumber value:value];
}];
}
@ -666,19 +639,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeSInt32SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSInt32NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSInt32:fieldNumber value:value];
}];
}
@ -693,19 +663,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeSInt64SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSInt64NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSInt64:fieldNumber value:value];
}];
}
@ -720,19 +687,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeSFixed64SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSFixed64NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSFixed64:fieldNumber value:value];
}];
}
@ -747,19 +711,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeSFixed32SizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSFixed32NoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeSFixed32:fieldNumber value:value];
}];
}
@ -774,19 +735,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(BOOL value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeBoolSizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(BOOL value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeBoolNoTag:value];
}];
} else {
[values enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateValuesWithBlock:^(BOOL value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeBool:fieldNumber value:value];
}];
}
@ -801,19 +759,16 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
if (tag != 0) {
if (values.count == 0) return;
__block size_t dataSize = 0;
[values enumerateRawValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateRawValuesWithBlock:^(int32_t value, __unused NSUInteger idx,__unused BOOL *stop) {
dataSize += GPBComputeEnumSizeNoTag(value);
}];
GPBWriteRawVarint32(&state_, tag);
GPBWriteRawVarint32(&state_, (int32_t)dataSize);
[values enumerateRawValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateRawValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeEnumNoTag:value];
}];
} else {
[values enumerateRawValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[values enumerateRawValuesWithBlock:^(int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[self writeEnum:fieldNumber value:value];
}];
}
@ -964,15 +919,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value
@end
size_t GPBComputeDoubleSizeNoTag(Float64 value) {
#pragma unused(value)
return LITTLE_ENDIAN_64_SIZE;
}
size_t GPBComputeDoubleSizeNoTag(__unused Float64 value) { return LITTLE_ENDIAN_64_SIZE; }
size_t GPBComputeFloatSizeNoTag(Float32 value) {
#pragma unused(value)
return LITTLE_ENDIAN_32_SIZE;
}
size_t GPBComputeFloatSizeNoTag(__unused Float32 value) { return LITTLE_ENDIAN_32_SIZE; }
size_t GPBComputeUInt64SizeNoTag(uint64_t value) { return GPBComputeRawVarint64Size(value); }
@ -991,20 +940,11 @@ size_t GPBComputeSizeTSizeAsInt32NoTag(size_t value) {
return GPBComputeInt32SizeNoTag((int32_t)value);
}
size_t GPBComputeFixed64SizeNoTag(uint64_t value) {
#pragma unused(value)
return LITTLE_ENDIAN_64_SIZE;
}
size_t GPBComputeFixed64SizeNoTag(__unused uint64_t value) { return LITTLE_ENDIAN_64_SIZE; }
size_t GPBComputeFixed32SizeNoTag(uint32_t value) {
#pragma unused(value)
return LITTLE_ENDIAN_32_SIZE;
}
size_t GPBComputeFixed32SizeNoTag(__unused uint32_t value) { return LITTLE_ENDIAN_32_SIZE; }
size_t GPBComputeBoolSizeNoTag(BOOL value) {
#pragma unused(value)
return 1;
}
size_t GPBComputeBoolSizeNoTag(__unused BOOL value) { return 1; }
size_t GPBComputeStringSizeNoTag(NSString *value) {
NSUInteger length = [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
@ -1029,15 +969,9 @@ size_t GPBComputeUInt32SizeNoTag(int32_t value) { return GPBComputeRawVarint32Si
size_t GPBComputeEnumSizeNoTag(int32_t value) { return GPBComputeInt32SizeNoTag(value); }
size_t GPBComputeSFixed32SizeNoTag(int32_t value) {
#pragma unused(value)
return LITTLE_ENDIAN_32_SIZE;
}
size_t GPBComputeSFixed32SizeNoTag(__unused int32_t value) { return LITTLE_ENDIAN_32_SIZE; }
size_t GPBComputeSFixed64SizeNoTag(int64_t value) {
#pragma unused(value)
return LITTLE_ENDIAN_64_SIZE;
}
size_t GPBComputeSFixed64SizeNoTag(__unused int64_t value) { return LITTLE_ENDIAN_64_SIZE; }
size_t GPBComputeSInt32SizeNoTag(int32_t value) {
return GPBComputeRawVarint32Size(GPBEncodeZigZag32(value));

@ -296,8 +296,7 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex, NSArray *allMessageField
return result;
}
- (id)copyWithZone:(NSZone *)zone {
#pragma unused(zone)
- (id)copyWithZone:(__unused NSZone *)zone {
return [self retain];
}
@ -997,8 +996,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
[super dealloc];
}
- (instancetype)copyWithZone:(NSZone *)zone {
#pragma unused(zone)
- (instancetype)copyWithZone:(__unused NSZone *)zone {
// Immutable.
return [self retain];
}

File diff suppressed because it is too large Load Diff

@ -953,13 +953,12 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
NSMutableDictionary *newDict =
[[NSMutableDictionary alloc] initWithCapacity:existingDict.count];
newValue = newDict;
[existingDict
enumerateKeysAndObjectsUsingBlock:^(NSString *key, GPBMessage *msg, BOOL *stop) {
#pragma unused(stop)
GPBMessage *copiedMsg = [msg copyWithZone:zone];
[newDict setObject:copiedMsg forKey:key];
[copiedMsg release];
}];
[existingDict enumerateKeysAndObjectsUsingBlock:^(NSString *key, GPBMessage *msg,
__unused BOOL *stop) {
GPBMessage *copiedMsg = [msg copyWithZone:zone];
[newDict setObject:copiedMsg forKey:key];
[copiedMsg release];
}];
} else {
// Is one of the GPB*ObjectDictionary classes. Type doesn't
// matter, just need one to invoke the selector.
@ -2909,8 +2908,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
#define CASE_REPEATED_POD_EXTRA(NAME, TYPE, ARRAY_TYPE, ARRAY_ACCESSOR_NAME) \
case GPBDataType##NAME: { \
GPB##ARRAY_TYPE##Array *array = genericArray; \
[array enumerate##ARRAY_ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) { \
_Pragma("unused(idx, stop)"); \
[array enumerate##ARRAY_ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, __unused NSUInteger idx, __unused BOOL *stop) { \
dataSize += GPBCompute##NAME##SizeNoTag(value); \
}]; \
break; \

@ -73,15 +73,12 @@ static uint32_t jenkins_one_at_a_time_hash(const char *key) {
// to worry about deallocation. All of the items are added to it at
// startup, and so the keys don't need to be retained/released.
// Keys are NULL terminated char *.
static const void *GPBRootExtensionKeyRetain(CFAllocatorRef allocator, const void *value) {
#pragma unused(allocator)
static const void *GPBRootExtensionKeyRetain(__unused CFAllocatorRef allocator, const void *value) {
return value;
}
static void GPBRootExtensionKeyRelease(CFAllocatorRef allocator, const void *value) {
#pragma unused(allocator)
#pragma unused(value)
}
static void GPBRootExtensionKeyRelease(__unused CFAllocatorRef allocator,
__unused const void *value) {}
static CFStringRef GPBRootExtensionCopyKeyDescription(const void *value) {
const char *key = (const char *)value;
@ -207,8 +204,7 @@ BOOL GPBResolveExtensionClassMethod(Class self, SEL sel) {
if (extension != nil) {
const char *encoding = GPBMessageEncodingForSelector(@selector(getClassValue), NO);
Class metaClass = objc_getMetaClass(class_getName(self));
IMP imp = imp_implementationWithBlock(^(id obj) {
#pragma unused(obj)
IMP imp = imp_implementationWithBlock(^(__unused id obj) {
return extension;
});
BOOL methodAdded = class_addMethod(metaClass, sel, imp, encoding);

@ -153,20 +153,20 @@
- (size_t)serializedSize {
__block size_t result = 0;
int32_t number = number_;
[mutableVarintList_ enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
result += GPBComputeUInt64Size(number, value);
}];
[mutableVarintList_
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeUInt64Size(number, value);
}];
[mutableFixed32List_ enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
result += GPBComputeFixed32Size(number, value);
}];
[mutableFixed32List_
enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeFixed32Size(number, value);
}];
[mutableFixed64List_ enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
result += GPBComputeFixed64Size(number, value);
}];
[mutableFixed64List_
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeFixed64Size(number, value);
}];
for (NSData *data in mutableLengthDelimitedList_) {
result += GPBComputeBytesSize(number, data);
@ -196,20 +196,20 @@
- (NSString *)description {
NSMutableString *description =
[NSMutableString stringWithFormat:@"<%@ %p>: Field: %d {\n", [self class], self, number_];
[mutableVarintList_ enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[description appendFormat:@"\t%llu\n", value];
}];
[mutableFixed32List_ enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[description appendFormat:@"\t%u\n", value];
}];
[mutableFixed64List_ enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[description appendFormat:@"\t%llu\n", value];
}];
[mutableVarintList_
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[description appendFormat:@"\t%llu\n", value];
}];
[mutableFixed32List_
enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[description appendFormat:@"\t%u\n", value];
}];
[mutableFixed64List_
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
[description appendFormat:@"\t%llu\n", value];
}];
for (NSData *data in mutableLengthDelimitedList_) {
[description appendFormat:@"\t%@\n", data];

@ -49,8 +49,7 @@ static void checkNumber(int32_t number) {
CFMutableDictionaryRef fields_;
}
static void CopyWorker(const void *key, const void *value, void *context) {
#pragma unused(key)
static void CopyWorker(__unused const void *key, const void *value, void *context) {
GPBUnknownField *field = value;
GPBUnknownFieldSet *result = context;
@ -184,8 +183,8 @@ static void CopyWorker(const void *key, const void *value, void *context) {
return description;
}
static void GPBUnknownFieldSetSerializedSize(const void *key, const void *value, void *context) {
#pragma unused(key)
static void GPBUnknownFieldSetSerializedSize(__unused const void *key, const void *value,
void *context) {
GPBUnknownField *field = value;
size_t *result = context;
*result += [field serializedSize];
@ -199,9 +198,8 @@ static void GPBUnknownFieldSetSerializedSize(const void *key, const void *value,
return result;
}
static void GPBUnknownFieldSetWriteAsMessageSetTo(const void *key, const void *value,
static void GPBUnknownFieldSetWriteAsMessageSetTo(__unused const void *key, const void *value,
void *context) {
#pragma unused(key)
GPBUnknownField *field = value;
GPBCodedOutputStream *output = context;
[field writeAsMessageSetExtensionToOutput:output];
@ -213,9 +211,8 @@ static void GPBUnknownFieldSetWriteAsMessageSetTo(const void *key, const void *v
}
}
static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key, const void *value,
void *context) {
#pragma unused(key)
static void GPBUnknownFieldSetSerializedSizeAsMessageSet(__unused const void *key,
const void *value, void *context) {
GPBUnknownField *field = value;
size_t *result = context;
*result += [field serializedSizeAsMessageSetExtension];
@ -266,9 +263,8 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key, const
return existing;
}
static void GPBUnknownFieldSetMergeUnknownFields(const void *key, const void *value,
static void GPBUnknownFieldSetMergeUnknownFields(__unused const void *key, const void *value,
void *context) {
#pragma unused(key)
GPBUnknownField *field = value;
GPBUnknownFieldSet *self = context;

@ -115,18 +115,16 @@ void GPBMessageDropUnknownFieldsRecursively(GPBMessage *initialMessage) {
switch (field.mapKeyDataType) {
case GPBDataTypeBool:
[(GPBBoolObjectDictionary *)rawFieldMap
enumerateKeysAndObjectsUsingBlock:^(BOOL key, id _Nonnull object,
BOOL *_Nonnull stop) {
#pragma unused(key, stop)
enumerateKeysAndObjectsUsingBlock:^(__unused BOOL key, id _Nonnull object,
__unused BOOL *_Nonnull stop) {
[todo addObject:object];
}];
break;
case GPBDataTypeFixed32:
case GPBDataTypeUInt32:
[(GPBUInt32ObjectDictionary *)rawFieldMap
enumerateKeysAndObjectsUsingBlock:^(uint32_t key, id _Nonnull object,
BOOL *_Nonnull stop) {
#pragma unused(key, stop)
enumerateKeysAndObjectsUsingBlock:^(__unused uint32_t key, id _Nonnull object,
__unused BOOL *_Nonnull stop) {
[todo addObject:object];
}];
break;
@ -134,18 +132,16 @@ void GPBMessageDropUnknownFieldsRecursively(GPBMessage *initialMessage) {
case GPBDataTypeSFixed32:
case GPBDataTypeSInt32:
[(GPBInt32ObjectDictionary *)rawFieldMap
enumerateKeysAndObjectsUsingBlock:^(int32_t key, id _Nonnull object,
BOOL *_Nonnull stop) {
#pragma unused(key, stop)
enumerateKeysAndObjectsUsingBlock:^(__unused int32_t key, id _Nonnull object,
__unused BOOL *_Nonnull stop) {
[todo addObject:object];
}];
break;
case GPBDataTypeFixed64:
case GPBDataTypeUInt64:
[(GPBUInt64ObjectDictionary *)rawFieldMap
enumerateKeysAndObjectsUsingBlock:^(uint64_t key, id _Nonnull object,
BOOL *_Nonnull stop) {
#pragma unused(key, stop)
enumerateKeysAndObjectsUsingBlock:^(__unused uint64_t key, id _Nonnull object,
__unused BOOL *_Nonnull stop) {
[todo addObject:object];
}];
break;
@ -153,17 +149,16 @@ void GPBMessageDropUnknownFieldsRecursively(GPBMessage *initialMessage) {
case GPBDataTypeSFixed64:
case GPBDataTypeSInt64:
[(GPBInt64ObjectDictionary *)rawFieldMap
enumerateKeysAndObjectsUsingBlock:^(int64_t key, id _Nonnull object,
BOOL *_Nonnull stop) {
#pragma unused(key, stop)
enumerateKeysAndObjectsUsingBlock:^(__unused int64_t key, id _Nonnull object,
__unused BOOL *_Nonnull stop) {
[todo addObject:object];
}];
break;
case GPBDataTypeString:
[(NSDictionary *)rawFieldMap
enumerateKeysAndObjectsUsingBlock:^(
NSString *_Nonnull key, GPBMessage *_Nonnull obj, BOOL *_Nonnull stop) {
#pragma unused(key, stop)
enumerateKeysAndObjectsUsingBlock:^(__unused NSString *_Nonnull key,
GPBMessage *_Nonnull obj,
__unused BOOL *_Nonnull stop) {
[todo addObject:obj];
}];
break;
@ -1604,8 +1599,7 @@ static void AppendTextFormatForMapMessageField(id map, GPBFieldDescriptor *field
if ((keyDataType == GPBDataTypeString) && GPBDataTypeIsObject(valueDataType)) {
// map is an NSDictionary.
NSDictionary *dict = map;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
#pragma unused(stop)
[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, __unused BOOL *stop) {
[toStr appendString:(isFirst ? msgStartFirst : msgStart)];
isFirst = NO;
@ -1997,11 +1991,11 @@ NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet, NSStri
for (GPBUnknownField *field in [unknownSet sortedFields]) {
int32_t fieldNumber = [field number];
#define PRINT_LOOP(PROPNAME, CTYPE, FORMAT) \
[field.PROPNAME enumerateValuesWithBlock:^(CTYPE value, NSUInteger idx, BOOL * stop) { \
_Pragma("unused(idx, stop)"); \
[result appendFormat:@"%@%d: " FORMAT "\n", lineIndent, fieldNumber, value]; \
}];
#define PRINT_LOOP(PROPNAME, CTYPE, FORMAT) \
[field.PROPNAME \
enumerateValuesWithBlock:^(CTYPE value, __unused NSUInteger idx, __unused BOOL * stop) { \
[result appendFormat:@"%@%d: " FORMAT "\n", lineIndent, fieldNumber, value]; \
}];
PRINT_LOOP(varintList, uint64_t, "%llu");
PRINT_LOOP(fixed32List, uint32_t, "0x%X");
@ -2180,14 +2174,12 @@ NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key, NSStri
// Shim from the older generated code into the runtime.
void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, GPBFieldDescriptor *field, int32_t value,
GPBFileSyntax syntax) {
#pragma unused(syntax)
__unused GPBFileSyntax syntax) {
GPBSetMessageInt32Field(self, field, value);
}
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, int32_t oneofHasIndex,
uint32_t fieldNumberNotToClear) {
#pragma unused(fieldNumberNotToClear)
__unused uint32_t fieldNumberNotToClear) {
#if defined(DEBUG) && DEBUG
NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof,
@"OneofDescriptor %@ doesn't appear to be for %@ messages.", oneof.name, [self class]);

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 47;
objectVersion = 55;
objects = {
/* Begin PBXBuildFile section */
@ -663,7 +663,7 @@
};
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ProtocolBuffers_OSX" */;
compatibilityVersion = "Xcode 6.3";
compatibilityVersion = "Xcode 13.0";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
@ -857,14 +857,21 @@
CLANG_ENABLE_OBJC_WEAK = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:identifier}";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
USER_HEADER_SEARCH_PATHS = "${PROJECT_DERIVED_FILE_DIR}/protos $(SRCROOT)";
USER_HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
@ -881,13 +888,20 @@
CLANG_ENABLE_OBJC_WEAK = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:identifier}";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_VERSION = 4.0;
USER_HEADER_SEARCH_PATHS = "${PROJECT_DERIVED_FILE_DIR}/protos $(SRCROOT)";
USER_HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
@ -952,7 +966,7 @@
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
MACOSX_DEPLOYMENT_TARGET = 10.9;
MACOSX_DEPLOYMENT_TARGET = 10.12;
ONLY_ACTIVE_ARCH = YES;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
@ -1021,10 +1035,11 @@
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
MACOSX_DEPLOYMENT_TARGET = 10.9;
MACOSX_DEPLOYMENT_TARGET = 10.12;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
USE_HEADERMAP = NO;
WARNING_CFLAGS = (
"-Wdocumentation-unknown-command",

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 47;
objectVersion = 55;
objects = {
/* Begin PBXBuildFile section */
@ -670,7 +670,7 @@
};
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ProtocolBuffers_iOS" */;
compatibilityVersion = "Xcode 6.3";
compatibilityVersion = "Xcode 13.0";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
@ -869,7 +869,11 @@
"$(inherited)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(DEVELOPER_DIR)/usr/lib\"",
@ -880,7 +884,10 @@
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "${PROJECT_DERIVED_FILE_DIR}/protos $(SRCROOT)";
USER_HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
@ -900,7 +907,11 @@
"$(inherited)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(DEVELOPER_DIR)/usr/lib\"",
@ -910,7 +921,10 @@
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "${PROJECT_DERIVED_FILE_DIR}/protos $(SRCROOT)";
USER_HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
@ -976,7 +990,7 @@
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
ONLY_ACTIVE_ARCH = YES;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = iphoneos;
@ -1045,10 +1059,11 @@
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
WARNING_CFLAGS = (
"-Wdocumentation-unknown-command",
"-Wundef",

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 47;
objectVersion = 55;
objects = {
/* Begin PBXBuildFile section */
@ -670,7 +670,7 @@
};
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ProtocolBuffers_tvOS" */;
compatibilityVersion = "Xcode 6.3";
compatibilityVersion = "Xcode 13.0";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
@ -865,7 +865,11 @@
"$(inherited)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(DEVELOPER_DIR)/usr/lib\"",
@ -875,7 +879,10 @@
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
USER_HEADER_SEARCH_PATHS = "${PROJECT_DERIVED_FILE_DIR}/protos $(SRCROOT)";
USER_HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
@ -895,7 +902,11 @@
"$(inherited)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(DEVELOPER_DIR)/usr/lib\"",
@ -904,7 +915,10 @@
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_VERSION = 4.0;
USER_HEADER_SEARCH_PATHS = "${PROJECT_DERIVED_FILE_DIR}/protos $(SRCROOT)";
USER_HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
@ -973,7 +987,7 @@
ONLY_ACTIVE_ARCH = YES;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = appletvos;
TVOS_DEPLOYMENT_TARGET = 9.0;
TVOS_DEPLOYMENT_TARGET = 12.0;
WARNING_CFLAGS = (
"-Wdocumentation-unknown-command",
"-Wundef",
@ -1041,8 +1055,9 @@
GENERATE_PROFILING_CODE = NO;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = appletvos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TVOS_DEPLOYMENT_TARGET = 9.0;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TVOS_DEPLOYMENT_TARGET = 12.0;
WARNING_CFLAGS = (
"-Wdocumentation-unknown-command",
"-Wundef",

@ -11,7 +11,7 @@ Requirements
The Objective C implementation requires:
- Objective C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X).
- Xcode 10.3 (or later).
- Xcode 13.3.1 (or later).
- The library code does *not* use ARC (for performance reasons), but it all can
be called from ARC code.

@ -101,13 +101,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
//% XCTAssertNotNil(array);
//% XCTAssertEqual(array.count, 0U);
//% XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
//% [array enumerateValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
//% #pragma unused(value, idx, stop)
//% [array enumerateValuesWithBlock:^(__unused TYPE value, __unused NSUInteger idx, __unused BOOL *stop) {
//% XCTFail(@"Shouldn't get here!");
//% }];
//% [array enumerateValuesWithOptions:NSEnumerationReverse
//% usingBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
//% #pragma unused(value, idx, stop)
//% usingBlock:^(__unused TYPE value, __unused NSUInteger idx, __unused BOOL *stop) {
//% XCTFail(@"Shouldn't get here!");
//% }];
//% [array release];
@ -445,13 +443,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];
@ -789,13 +785,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];
@ -1133,13 +1127,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused int64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];
@ -1477,13 +1469,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];
@ -1821,13 +1811,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused float value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(float value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused float value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];
@ -2165,13 +2153,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused double value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(double value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused double value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];
@ -2509,13 +2495,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused BOOL value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused BOOL value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];
@ -2853,13 +2837,11 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
XCTAssertNotNil(array);
XCTAssertEqual(array.count, 0U);
XCTAssertThrowsSpecificNamed([array valueAtIndex:0], NSException, NSRangeException);
[array enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
[array enumerateValuesWithBlock:^(__unused int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array enumerateValuesWithOptions:NSEnumerationReverse
usingBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(value, idx, stop)
usingBlock:^(__unused int32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[array release];

@ -58,8 +58,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt32:NULL forKey:YES]);
[dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused BOOL aKey, __unused uint32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -125,8 +124,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused BOOL aKey, __unused uint32_t aValue, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -363,8 +361,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt32:NULL forKey:YES]);
[dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused BOOL aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -430,8 +427,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused BOOL aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -668,8 +664,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt64:NULL forKey:YES]);
[dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused BOOL aKey, __unused uint64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -735,8 +730,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused BOOL aKey, __unused uint64_t aValue, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -973,8 +967,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt64:NULL forKey:YES]);
[dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused BOOL aKey, __unused int64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1040,8 +1033,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused BOOL aKey, __unused int64_t aValue, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1278,8 +1270,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getBool:NULL forKey:YES]);
[dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused BOOL aKey, __unused BOOL aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1345,8 +1336,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused BOOL aKey, __unused BOOL aValue, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1583,8 +1573,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getFloat:NULL forKey:YES]);
[dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused BOOL aKey, __unused float aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1650,8 +1639,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused BOOL aKey, __unused float aValue, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1888,8 +1876,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getDouble:NULL forKey:YES]);
[dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused BOOL aKey, __unused double aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1955,8 +1942,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused BOOL aKey, __unused double aValue, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2193,8 +2179,7 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:YES]);
[dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused BOOL aKey, __unused NSString* aObject, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2252,8 +2237,7 @@
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused BOOL aKey, __unused NSString* aObject, BOOL *stop) {
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;

@ -89,8 +89,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt32:NULL forKey:11]);
[dict enumerateKeysAndUInt32sUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused int32_t aKey, __unused uint32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -160,8 +159,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt32sUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused int32_t aKey, __unused uint32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -450,8 +448,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt32:NULL forKey:11]);
[dict enumerateKeysAndInt32sUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused int32_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -521,8 +518,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt32sUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused int32_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -811,8 +807,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt64:NULL forKey:11]);
[dict enumerateKeysAndUInt64sUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused int32_t aKey, __unused uint64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -882,8 +877,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt64sUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused int32_t aKey, __unused uint64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1172,8 +1166,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt64:NULL forKey:11]);
[dict enumerateKeysAndInt64sUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused int32_t aKey, __unused int64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1243,8 +1236,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt64sUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused int32_t aKey, __unused int64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1533,8 +1525,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getBool:NULL forKey:11]);
[dict enumerateKeysAndBoolsUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused int32_t aKey, __unused BOOL aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1604,8 +1595,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndBoolsUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused int32_t aKey, __unused BOOL aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1894,8 +1884,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getFloat:NULL forKey:11]);
[dict enumerateKeysAndFloatsUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused int32_t aKey, __unused float aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1965,8 +1954,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndFloatsUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused int32_t aKey, __unused float aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2255,8 +2243,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getDouble:NULL forKey:11]);
[dict enumerateKeysAndDoublesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused int32_t aKey, __unused double aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2326,8 +2313,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndDoublesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused int32_t aKey, __unused double aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2616,8 +2602,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getEnum:NULL forKey:11]);
[dict enumerateKeysAndEnumsUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused int32_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2687,8 +2672,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndEnumsUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused int32_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3045,8 +3029,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndRawValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndRawValuesUsingBlock:^(__unused int32_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3395,8 +3378,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:11]);
[dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused int32_t aKey, __unused NSString* aObject, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -3456,8 +3438,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused int32_t aKey, __unused NSString* aObject, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;

@ -89,8 +89,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt32:NULL forKey:21LL]);
[dict enumerateKeysAndUInt32sUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused int64_t aKey, __unused uint32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -160,8 +159,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt32sUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused int64_t aKey, __unused uint32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -450,8 +448,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt32:NULL forKey:21LL]);
[dict enumerateKeysAndInt32sUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused int64_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -521,8 +518,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt32sUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused int64_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -811,8 +807,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt64:NULL forKey:21LL]);
[dict enumerateKeysAndUInt64sUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused int64_t aKey, __unused uint64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -882,8 +877,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt64sUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused int64_t aKey, __unused uint64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1172,8 +1166,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt64:NULL forKey:21LL]);
[dict enumerateKeysAndInt64sUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused int64_t aKey, __unused int64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1243,8 +1236,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt64sUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused int64_t aKey, __unused int64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1533,8 +1525,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getBool:NULL forKey:21LL]);
[dict enumerateKeysAndBoolsUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused int64_t aKey, __unused BOOL aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1604,8 +1595,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndBoolsUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused int64_t aKey, __unused BOOL aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1894,8 +1884,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getFloat:NULL forKey:21LL]);
[dict enumerateKeysAndFloatsUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused int64_t aKey, __unused float aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1965,8 +1954,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndFloatsUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused int64_t aKey, __unused float aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2255,8 +2243,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getDouble:NULL forKey:21LL]);
[dict enumerateKeysAndDoublesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused int64_t aKey, __unused double aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2326,8 +2313,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndDoublesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused int64_t aKey, __unused double aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2616,8 +2602,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getEnum:NULL forKey:21LL]);
[dict enumerateKeysAndEnumsUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused int64_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2687,8 +2672,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndEnumsUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused int64_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3045,8 +3029,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndRawValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndRawValuesUsingBlock:^(__unused int64_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3395,8 +3378,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:21LL]);
[dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused int64_t aKey, __unused NSString* aObject, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -3456,8 +3438,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused int64_t aKey, __unused NSString* aObject, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;

@ -89,8 +89,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]);
[dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused NSString *aKey, __unused uint32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -160,8 +159,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused NSString *aKey, __unused uint32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -450,8 +448,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]);
[dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -521,8 +518,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -811,8 +807,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]);
[dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused NSString *aKey, __unused uint64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -882,8 +877,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused NSString *aKey, __unused uint64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1172,8 +1166,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]);
[dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused NSString *aKey, __unused int64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1243,8 +1236,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused NSString *aKey, __unused int64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1533,8 +1525,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getBool:NULL forKey:@"foo"]);
[dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused NSString *aKey, __unused BOOL aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1604,8 +1595,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused NSString *aKey, __unused BOOL aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1894,8 +1884,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]);
[dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused NSString *aKey, __unused float aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1965,8 +1954,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused NSString *aKey, __unused float aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2255,8 +2243,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]);
[dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused NSString *aKey, __unused double aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2326,8 +2313,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused NSString *aKey, __unused double aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2616,8 +2602,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
[dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2687,8 +2672,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3045,8 +3029,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndRawValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndRawValuesUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;

@ -89,8 +89,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt32:NULL forKey:1U]);
[dict enumerateKeysAndUInt32sUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused uint32_t aKey, __unused uint32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -160,8 +159,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt32sUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused uint32_t aKey, __unused uint32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -450,8 +448,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt32:NULL forKey:1U]);
[dict enumerateKeysAndInt32sUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused uint32_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -521,8 +518,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt32sUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused uint32_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -811,8 +807,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt64:NULL forKey:1U]);
[dict enumerateKeysAndUInt64sUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused uint32_t aKey, __unused uint64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -882,8 +877,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt64sUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused uint32_t aKey, __unused uint64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1172,8 +1166,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt64:NULL forKey:1U]);
[dict enumerateKeysAndInt64sUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused uint32_t aKey, __unused int64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1243,8 +1236,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt64sUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused uint32_t aKey, __unused int64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1533,8 +1525,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getBool:NULL forKey:1U]);
[dict enumerateKeysAndBoolsUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused uint32_t aKey, __unused BOOL aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1604,8 +1595,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndBoolsUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused uint32_t aKey, __unused BOOL aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1894,8 +1884,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getFloat:NULL forKey:1U]);
[dict enumerateKeysAndFloatsUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused uint32_t aKey, __unused float aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1965,8 +1954,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndFloatsUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused uint32_t aKey, __unused float aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2255,8 +2243,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getDouble:NULL forKey:1U]);
[dict enumerateKeysAndDoublesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused uint32_t aKey, __unused double aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2326,8 +2313,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndDoublesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused uint32_t aKey, __unused double aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2616,8 +2602,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getEnum:NULL forKey:1U]);
[dict enumerateKeysAndEnumsUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused uint32_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2687,8 +2672,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndEnumsUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused uint32_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3045,8 +3029,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndRawValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndRawValuesUsingBlock:^(__unused uint32_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3395,8 +3378,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:1U]);
[dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused uint32_t aKey, __unused NSString* aObject, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -3456,8 +3438,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused uint32_t aKey, __unused NSString* aObject, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;

@ -89,8 +89,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt32:NULL forKey:31ULL]);
[dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused uint64_t aKey, __unused uint32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -160,8 +159,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt32sUsingBlock:^(__unused uint64_t aKey, __unused uint32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -450,8 +448,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt32:NULL forKey:31ULL]);
[dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -521,8 +518,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt32sUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -811,8 +807,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getUInt64:NULL forKey:31ULL]);
[dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused uint64_t aKey, __unused uint64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -882,8 +877,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndUInt64sUsingBlock:^(__unused uint64_t aKey, __unused uint64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1172,8 +1166,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getInt64:NULL forKey:31ULL]);
[dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused uint64_t aKey, __unused int64_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1243,8 +1236,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndInt64sUsingBlock:^(__unused uint64_t aKey, __unused int64_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1533,8 +1525,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getBool:NULL forKey:31ULL]);
[dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused uint64_t aKey, __unused BOOL aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1604,8 +1595,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndBoolsUsingBlock:^(__unused uint64_t aKey, __unused BOOL aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -1894,8 +1884,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getFloat:NULL forKey:31ULL]);
[dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused uint64_t aKey, __unused float aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -1965,8 +1954,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndFloatsUsingBlock:^(__unused uint64_t aKey, __unused float aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2255,8 +2243,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getDouble:NULL forKey:31ULL]);
[dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused uint64_t aKey, __unused double aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2326,8 +2313,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndDoublesUsingBlock:^(__unused uint64_t aKey, __unused double aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -2616,8 +2602,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertFalse([dict getEnum:NULL forKey:31ULL]);
[dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -2687,8 +2672,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndEnumsUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3045,8 +3029,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndRawValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
[dict enumerateKeysAndRawValuesUsingBlock:^(__unused uint64_t aKey, __unused int32_t aValue, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;
@ -3395,8 +3378,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:31ULL]);
[dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused uint64_t aKey, __unused NSString* aObject, __unused BOOL *stop) {
XCTFail(@"Shouldn't get here!");
}];
[dict release];
@ -3456,8 +3438,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
[dict enumerateKeysAndObjectsUsingBlock:^(__unused uint64_t aKey, __unused NSString* aObject, BOOL *stop) {
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
++idx;

@ -70,8 +70,7 @@
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 0U);
//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY1)
//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u, stop)
//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(__unused KEY_TYPE KisP##aKey, __unused VALUE_TYPE a##VNAME$u, __unused BOOL *stop) {
//% XCTFail(@"Shouldn't get here!");
//% }];
//% [dict release];
@ -131,8 +130,7 @@
//%
//% // Stopping the enumeration.
//% idx = 0;
//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u)
//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(__unused KEY_TYPE KisP##aKey, __unused VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% if (idx == 1) *stop = YES;
//% XCTAssertNotEqual(idx, 2U);
//% ++idx;
@ -425,8 +423,7 @@
//%
//% // Stopping the enumeration.
//% idx = 0;
//% [dict enumerateKeysAndRawValuesUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE aValue, BOOL *stop) {
//% #pragma unused(aKey, aValue)
//% [dict enumerateKeysAndRawValuesUsingBlock:^(__unused KEY_TYPE KisP##aKey, __unused VALUE_TYPE aValue, BOOL *stop) {
//% if (idx == 1) *stop = YES;
//% XCTAssertNotEqual(idx, 2U);
//% ++idx;
@ -790,8 +787,7 @@
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 0U);
//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY1)
//% [dict enumerateKeysAnd##VALUE_NAME##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u##, stop)
//% [dict enumerateKeysAnd##VALUE_NAME##sUsingBlock:^(__unused KEY_TYPE KisP##aKey, __unused VALUE_TYPE a##VNAME$u##, __unused BOOL *stop) {
//% XCTFail(@"Shouldn't get here!");
//% }];
//% [dict release];
@ -849,8 +845,7 @@
//%
//% // Stopping the enumeration.
//% idx = 0;
//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u)
//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(__unused KEY_TYPE KisP##aKey, __unused VALUE_TYPE a##VNAME$u##, BOOL *stop) {
//% if (idx == 0) *stop = YES;
//% XCTAssertNotEqual(idx, 2U);
//% ++idx;

@ -2600,8 +2600,7 @@
// Ensure the messages are unique per map.
[msg1.mapInt32ForeignMessage
enumerateKeysAndObjectsUsingBlock:^(int32_t key, id value, BOOL *stop) {
#pragma unused(stop)
enumerateKeysAndObjectsUsingBlock:^(int32_t key, id value, __unused BOOL *stop) {
ForeignMessage *subMsg2 = [msg2.mapInt32ForeignMessage objectForKey:key];
XCTAssertNotEqual(value, subMsg2); // Ptr compare, new object.
}];

@ -74,12 +74,9 @@
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
#pragma unused(object)
#pragma unused(change)
#pragma unused(context)
ofObject:(__unused id)object
change:(__unused NSDictionary *)change
context:(__unused void *)context {
if ([keyPath isEqualToString:keyPath_]) {
self.didObserve = YES;
}

@ -363,11 +363,11 @@ cc_dist_library(
}),
tags = ["manual"],
deps = [
"//src/google/protobuf:wkt_cc_proto",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf:arena",
"//src/google/protobuf:port_def",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf:wkt_cc_proto",
"//src/google/protobuf:port_def",
"//src/google/protobuf/compiler:importer",
"//src/google/protobuf/io",
"//src/google/protobuf/io:gzip_stream",
@ -402,10 +402,18 @@ cc_dist_library(
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf/compiler:command_line_interface",
"//src/google/protobuf/compiler/cpp",
"//src/google/protobuf/compiler/cpp:names",
"//src/google/protobuf/compiler/cpp:names_internal",
"//src/google/protobuf/compiler/csharp",
"//src/google/protobuf/compiler/csharp:names",
"//src/google/protobuf/compiler/java",
"//src/google/protobuf/compiler/java:names",
"//src/google/protobuf/compiler/java:names_internal",
"//src/google/protobuf/compiler/objectivec",
"//src/google/protobuf/compiler/objectivec:names",
"//src/google/protobuf/compiler/objectivec:names_internal",
"//src/google/protobuf/compiler/php",
"//src/google/protobuf/compiler/php:names",
"//src/google/protobuf/compiler/python",
"//src/google/protobuf/compiler/ruby",
],
@ -425,11 +433,11 @@ cc_dist_library(
deps = [
"//src/google/protobuf:test_util",
"//src/google/protobuf:test_util2",
"//src/google/protobuf/compiler:annotation_test_util",
"//src/google/protobuf/compiler/cpp:unittest_lib",
"//src/google/protobuf/util/internal:expecting_objectwriter",
"//src/google/protobuf/util/internal:mock_error_listener",
"//src/google/protobuf/util/internal:type_info_test_helper",
"//src/google/protobuf/compiler:annotation_test_util",
"//src/google/protobuf/compiler/cpp:unittest_lib",
],
)
@ -438,11 +446,12 @@ cc_dist_library(
testonly = 1,
tags = ["manual"],
deps = [
"//src/google/protobuf/compiler:mock_code_generator",
"//src/google/protobuf/testing",
"//src/google/protobuf/compiler:mock_code_generator",
],
)
################################################################################
# Distribution sources
################################################################################

@ -1,161 +0,0 @@
# Build scripts that publish pre-compiled protoc artifacts
``protoc`` is the compiler for ``.proto`` files. It generates language bindings
for the messages and/or RPC services from ``.proto`` files.
Because ``protoc`` is a native executable, the scripts under this directory
build and publish a ``protoc`` executable (a.k.a. artifact) to Maven
repositories. The artifact can be used by build automation tools so that users
would not need to compile and install ``protoc`` for their systems.
If you would like us to publish protoc artifact for a new platform, please send
us a pull request to add support for the new platform. You would need to change
the following files:
* [build-protoc.sh](build-protoc.sh): script to cross-build the protoc for your
platform.
* [pom.xml](pom.xml): script to upload artifacts to maven.
* [build-zip.sh](build-zip.sh): script to package published maven artifacts in
our release page.
## Maven Location
The published protoc artifacts are available on Maven here:
https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/
## Versioning
The version of the ``protoc`` artifact must be the same as the version of the
Protobuf project.
## Artifact name
The name of a published ``protoc`` artifact is in the following format:
``protoc-<version>-<os>-<arch>.exe``, e.g., ``protoc-3.6.1-linux-x86_64.exe``.
Note that artifacts for linux/macos also have the `.exe` suffix but they are
not windows binaries.
## System requirement
Install [Apache Maven](http://maven.apache.org/) if you don't have it.
The scripts only work under Unix-like environments, e.g., Linux, MacOSX, and
Cygwin or MinGW for Windows. Please see ``README.md`` of the Protobuf project
for how to set up the build environment.
## Building from a freshly checked-out source
If you just checked out the Protobuf source from github, you need to
pull in any submodules.
Under the protobuf project directory:
```
git submodule update --init --recursive
```
### Build the artifact for each platform
Run the build-protoc.sh script under this protoc-artifacts directory to build the protoc
artifact for each platform. For example:
```
$ cd protoc-artifacts
$ ./build-protoc.sh linux x86_64 protoc
```
The above command will produce a `target/linux/x86_64/protoc` binary under the
protoc-artifacts directory.
For a list of supported platforms, see the comments in the build-protoc.sh
script. We only use this script to build artifacts on Ubuntu and MacOS (both
with x86_64, and do cross-compilation for other platforms.
### Tips for building for Linux
We build on Centos 6.9 to provide a good compatibility for not very new
systems. We have provided a ``Dockerfile`` under this directory to build the
environment. It has been tested with Docker 1.6.1.
To build a image:
```
$ docker build -t protoc-artifacts .
```
To run the image:
```
$ docker run -it --rm=true protoc-artifacts bash
```
To checkout protobuf (run within the container):
```
$ # Replace v3.5.1 with the version you want
$ wget -O - https://github.com/protocolbuffers/protobuf/archive/v3.5.1.tar.gz | tar xvzp
```
### Windows build
We no longer use scripts in this directory to build windows artifacts. Instead,
we use Visual Studio 2015 to build our windows release artifacts. See our
[kokoro windows build scripts here](../kokoro/release/protoc/windows/build.bat).
To upload windows artifacts, copy the built binaries into this directory and
put it into the target/windows/(x86_64|x86_32) directory the same way as the
artifacts for other platforms. That will allow the maven script to find and
upload the artifacts to maven.
## To push artifacts to Maven Central
Before you can upload artifacts to Maven Central repository, make sure you have
read [this page](http://central.sonatype.org/pages/apache-maven.html) on how to
configure GPG and Sonatype account.
Before you do the deployment, make sure you have built the protoc artifacts for
every supported platform and put them under the target directory. Example
target directory layout:
+ pom.xml
+ target
+ linux
+ x86_64
protoc.exe
+ x86_32
protoc.exe
+ aarch_64
protoc.exe
+ ppcle_64
protoc.exe
+ s390_64
protoc.exe
+ osx
+ x86_64
protoc.exe
+ x86_32
protoc.exe
+ windows
+ x86_64
protoc.exe
+ x86_32
protoc.exe
You will need to build the artifacts on multiple machines and gather them
together into one place.
Use the following command to deploy artifacts for the host platform to a
staging repository.
```
$ mvn deploy -P release
```
It creates a new staging repository. Go to
https://oss.sonatype.org/#stagingRepositories and find the repository, usually
in the name like ``comgoogle-123``. Verify that the staging repository has all
the binaries, close and release this repository.
## Tested build environments
We have successfully built artifacts on the following environments:
- Linux x86_32 and x86_64:
- Centos 6.9 (within Docker 1.6.1)
- Ubuntu 14.04.5 64-bit
- Linux aarch_64: Cross compiled with `g++-aarch64-linux-gnu` on Ubuntu 14.04.5 64-bit
- Mac OS X x86_32 and x86_64: Mac OS X 10.9.5

@ -1,120 +0,0 @@
#!/bin/bash
if [ $# -ne 2 ]; then
cat <<EOF
Usage: $0 <TARGET> <VERSION_NUMBER>
TARGET: protoc | protoc-gen-javalite
Example:
$ $0 protoc 3.0.0
$ $0 protoc-gen-javalite 3.0.0
This script will download pre-built protoc or protoc plugin binaries from maven
repository and create .zip packages suitable to be included in the github
release page. If the target is protoc, well-known type .proto files will also be
included. Each invocation will create 8 zip packages:
dist/<TARGET>-<VERSION_NUMBER>-win32.zip
dist/<TARGET>-<VERSION_NUMBER>-win64.zip
dist/<TARGET>-<VERSION_NUMBER>-osx-aarch_64.zip
dist/<TARGET>-<VERSION_NUMBER>-osx-x86_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-x86_32.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-x86_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-aarch_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-ppcle_64.zip
dist/<TARGET>-<VERSION_NUMBER>-linux-s390_64.zip
EOF
exit 1
fi
TARGET=$1
VERSION_NUMBER=$2
# <zip file name> <binary file name> pairs.
declare -a FILE_NAMES=( \
win32.zip windows-x86_32.exe \
win64.zip windows-x86_64.exe \
osx-aarch_64.zip osx-aarch_64.exe \
osx-x86_64.zip osx-x86_64.exe \
linux-x86_32.zip linux-x86_32.exe \
linux-x86_64.zip linux-x86_64.exe \
linux-aarch_64.zip linux-aarch_64.exe \
linux-ppcle_64.zip linux-ppcle_64.exe \
linux-s390_64.zip linux-s390_64.exe \
)
# List of all well-known types to be included.
declare -a WELL_KNOWN_TYPES=( \
google/protobuf/descriptor.proto \
google/protobuf/any.proto \
google/protobuf/api.proto \
google/protobuf/duration.proto \
google/protobuf/empty.proto \
google/protobuf/field_mask.proto \
google/protobuf/source_context.proto \
google/protobuf/struct.proto \
google/protobuf/timestamp.proto \
google/protobuf/type.proto \
google/protobuf/wrappers.proto \
google/protobuf/compiler/plugin.proto \
)
set -e
# A temporary working directory to put all files.
DIR=$(mktemp -d)
# Copy over well-known types.
mkdir -p ${DIR}/include/google/protobuf/compiler
for PROTO in ${WELL_KNOWN_TYPES[@]}; do
cp -f ../src/${PROTO} ${DIR}/include/${PROTO}
done
# Create a readme file.
cat <<EOF > ${DIR}/readme.txt
Protocol Buffers - Google's data interchange format
Copyright 2008 Google Inc.
https://developers.google.com/protocol-buffers/
This package contains a precompiled binary version of the protocol buffer
compiler (protoc). This binary is intended for users who want to use Protocol
Buffers in languages other than C++ but do not want to compile protoc
themselves. To install, simply place this binary somewhere in your PATH.
If you intend to use the included well known types then don't forget to
copy the contents of the 'include' directory somewhere as well, for example
into '/usr/local/include/'.
Please refer to our official github site for more installation instructions:
https://github.com/protocolbuffers/protobuf
EOF
mkdir -p dist
mkdir -p ${DIR}/bin
# Create a zip file for each binary.
for((i=0;i<${#FILE_NAMES[@]};i+=2));do
ZIP_NAME=${FILE_NAMES[$i]}
if [ ${ZIP_NAME:0:3} = "win" ]; then
BINARY="$TARGET.exe"
else
BINARY="$TARGET"
fi
BINARY_NAME=${FILE_NAMES[$(($i+1))]}
BINARY_URL=https://repo1.maven.org/maven2/com/google/protobuf/$TARGET/${VERSION_NUMBER}/$TARGET-${VERSION_NUMBER}-${BINARY_NAME}
if ! wget ${BINARY_URL} -O ${DIR}/bin/$BINARY &> /dev/null; then
echo "[ERROR] Failed to download ${BINARY_URL}" >&2
echo "[ERROR] Skipped $TARGET-${VERSION_NAME}-${ZIP_NAME}" >&2
continue
fi
TARGET_ZIP_FILE=`pwd`/dist/$TARGET-${VERSION_NUMBER}-${ZIP_NAME}
pushd $DIR &> /dev/null
chmod +x bin/$BINARY
if [ "$TARGET" = "protoc" ]; then
zip -r ${TARGET_ZIP_FILE} include bin readme.txt &> /dev/null
else
zip -r ${TARGET_ZIP_FILE} bin &> /dev/null
fi
rm bin/$BINARY
popd &> /dev/null
echo "[INFO] Successfully created ${TARGET_ZIP_FILE}"
done

@ -1,144 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.google</groupId>
<artifactId>google</artifactId>
<version>5</version>
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<version>3.21.6</version>
<packaging>pom</packaging>
<name>Protobuf Compiler</name>
<description>
Protobuf Compiler (protoc) is a compiler for .proto files. It generates
language-specific code for Protobuf messages and RPC interfaces.
</description>
<inceptionYear>2008</inceptionYear>
<url>https://developers.google.com/protocol-buffers/</url>
<licenses>
<license>
<name>BSD-3-Clause</name>
<url>https://opensource.org/licenses/BSD-3-Clause</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>https://github.com/protocolbuffers/protobuf</url>
<connection>
scm:git:https://github.com/protocolbuffers/protobuf.git
</connection>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${basedir}/target/linux/x86_64/protoc.exe</file>
<classifier>linux-x86_64</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/linux/x86_32/protoc.exe</file>
<classifier>linux-x86_32</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/windows/x86_64/protoc.exe</file>
<classifier>windows-x86_64</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/windows/x86_32/protoc.exe</file>
<classifier>windows-x86_32</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/osx/x86_64/protoc.exe</file>
<classifier>osx-x86_64</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/osx/aarch_64/protoc.exe</file>
<classifier>osx-aarch_64</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/linux/aarch_64/protoc.exe</file>
<classifier>linux-aarch_64</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/linux/ppcle_64/protoc.exe</file>
<classifier>linux-ppcle_64</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/linux/s390_64/protoc.exe</file>
<classifier>linux-s390_64</classifier>
<type>exe</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<properties>
<!-- Specify the staging repository to deploy to. This can be left
empty for the first deployment, and Sonatype will create one. For
subsequent deployments it should be set to what Sonatype has
created, so that all deployments will go to the same repository.
-->
<staging.repository/>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<extensions>true</extensions>
<configuration>
<serverId>sonatype-nexus-staging</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<skipStagingRepositoryClose>true</skipStagingRepositoryClose>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
<stagingRepositoryId>${staging.repository}</stagingRepositoryId>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

@ -1,13 +0,0 @@
#!/bin/bash
set -eu -o pipefail
quote() {
local arg
for arg in "$@"; do
printf "'"
printf "%s" "$arg" | sed -e "s/'/'\\\\''/g"
printf "' "
done
}
exec scl enable devtoolset-2 "$(quote "$@")"

@ -318,6 +318,7 @@ set(libprotoc_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/names.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/context.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/doc_comment.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum.cc
@ -342,24 +343,26 @@ set(libprotoc_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_serialization.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/name_resolver.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/names.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/primitive_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/service.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/shared_code_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/names.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_file.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/names.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/php_generator.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.cc
@ -402,7 +405,6 @@ set(libprotoc_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_map_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_message.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_message_field.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_primitive_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
@ -411,6 +413,7 @@ set(libprotoc_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/context.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/doc_comment.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum.h
@ -443,6 +446,7 @@ set(libprotoc_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/shared_code_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field_lite.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_extension.h
@ -457,6 +461,7 @@ set(libprotoc_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_options.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/names.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/php_generator.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.h
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h

@ -53,17 +53,6 @@
namespace google {
namespace protobuf {
namespace internal {
namespace {
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ArenaBlock
kSentryArenaBlock = {};
ArenaBlock* SentryArenaBlock() {
// const_cast<> is okay as kSentryArenaBlock will never be mutated.
return const_cast<ArenaBlock*>(&kSentryArenaBlock);
}
} // namespace
static SerialArena::Memory AllocateMemory(const AllocationPolicy* policy_ptr,
size_t last_size, size_t min_bytes) {
@ -116,26 +105,28 @@ class GetDeallocator {
size_t* space_allocated_;
};
constexpr ArenaBlock SerialArena::kSentryBlock;
// It is guaranteed that this is constructed in `b`. IOW, this is not the first
// arena and `b` cannot be sentry.
SerialArena::SerialArena(ArenaBlock* b, ThreadSafeArena& parent)
: ptr_{b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize)},
limit_{b->Limit()},
head_{b},
space_allocated_{b->size},
space_allocated_{b->size()},
parent_{parent} {
GOOGLE_DCHECK(!b->IsSentry());
}
// It is guaranteed that this is the first SerialArena. Use sentry block.
SerialArena::SerialArena(ThreadSafeArena& parent)
: head_{SentryArenaBlock()}, parent_{parent} {}
: head_{SentryBlock()}, parent_{parent} {}
// It is guaranteed that this is the first SerialArena but `b` may be user
// provided or newly allocated to store AllocationPolicy.
SerialArena::SerialArena(FirstSerialArena, ArenaBlock* b,
ThreadSafeArena& parent)
: head_{b}, space_allocated_{b->size}, parent_{parent} {
: head_{b}, space_allocated_{b->size()}, parent_{parent} {
if (b->IsSentry()) return;
set_ptr(b->Pointer(kBlockHeaderSize));
@ -145,9 +136,9 @@ SerialArena::SerialArena(FirstSerialArena, ArenaBlock* b,
void SerialArena::Init(ArenaBlock* b, size_t offset) {
set_ptr(b->Pointer(offset));
limit_ = b->Limit();
head_.relaxed_set(b);
set_head(b);
space_used_.relaxed_set(0);
space_allocated_.relaxed_set(b->size);
space_allocated_.relaxed_set(b->size());
cached_block_length_ = 0;
cached_blocks_ = nullptr;
}
@ -164,11 +155,11 @@ SerialArena* SerialArena::New(Memory mem, ThreadSafeArena& parent) {
template <typename Deallocator>
SerialArena::Memory SerialArena::Free(Deallocator deallocator) {
ArenaBlock* b = head();
Memory mem = {b, b->size};
Memory mem = {b, b->size()};
while (b->next) {
b = b->next; // We must first advance before deleting this block
deallocator(mem);
mem = {b, b->size};
mem = {b, b->size()};
}
return mem;
}
@ -204,7 +195,7 @@ void SerialArena::AllocateNewBlock(size_t n) {
// Record how much used in this block.
used = static_cast<size_t>(ptr() - old_head->Pointer(kBlockHeaderSize));
wasted = old_head->size - used;
wasted = old_head->size() - used;
space_used_.relaxed_set(space_used_.relaxed_get() + used);
}
@ -213,7 +204,7 @@ void SerialArena::AllocateNewBlock(size_t n) {
// but with a CPU regression. The regression might have been an artifact of
// the microbenchmark.
auto mem = AllocateMemory(parent_.AllocPolicy(), old_head->size, n);
auto mem = AllocateMemory(parent_.AllocPolicy(), old_head->size(), n);
// We don't want to emit an expensive RMW instruction that requires
// exclusive access to a cacheline. Hence we write it in terms of a
// regular add.
@ -222,10 +213,9 @@ void SerialArena::AllocateNewBlock(size_t n) {
/*used=*/used,
/*allocated=*/mem.size, wasted);
auto* new_head = new (mem.ptr) ArenaBlock{old_head, mem.size};
set_head(new_head);
set_ptr(new_head->Pointer(kBlockHeaderSize));
limit_ = new_head->Limit();
// Previous writes must take effect before writing new head.
head_.atomic_set(new_head);
#ifdef ADDRESS_SANITIZER
ASAN_POISON_MEMORY_REGION(ptr(), limit_ - ptr());
@ -240,10 +230,10 @@ uint64_t SerialArena::SpaceUsed() const {
// usage of the *current* block.
// TODO(mkruskal) Consider eliminating this race in exchange for a possible
// performance hit on ARM (see cl/455186837).
const ArenaBlock* h = head_.atomic_get();
const ArenaBlock* h = head();
if (h->IsSentry()) return 0;
const uint64_t current_block_size = h->size;
const uint64_t current_block_size = h->size();
uint64_t current_space_used = std::min(
static_cast<uint64_t>(
ptr() - const_cast<ArenaBlock*>(h)->Pointer(kBlockHeaderSize)),
@ -318,7 +308,7 @@ void SerialArena::CleanupList() {
// where the size of "ids" and "arenas" is determined at runtime; hence the use
// of Layout.
struct SerialArenaChunkHeader {
PROTOBUF_CONSTEXPR SerialArenaChunkHeader(uint32_t capacity, uint32_t size)
constexpr SerialArenaChunkHeader(uint32_t capacity, uint32_t size)
: next_chunk(nullptr), capacity(capacity), size(size) {}
ThreadSafeArena::SerialArenaChunk* next_chunk;
@ -401,7 +391,7 @@ class ThreadSafeArena::SerialArenaChunk {
}
id(idx).relaxed_set(me);
arena(idx).atomic_set(serial);
arena(idx).relaxed_set(serial);
return true;
}
@ -443,7 +433,7 @@ class ThreadSafeArena::SerialArenaChunk {
}
};
PROTOBUF_CONSTEXPR SerialArenaChunkHeader kSentryArenaChunk = {0, 0};
constexpr SerialArenaChunkHeader kSentryArenaChunk = {0, 0};
ThreadSafeArena::SerialArenaChunk* ThreadSafeArena::SentrySerialArenaChunk() {
// const_cast is okay because the sentry chunk is never mutated. Also,
@ -497,7 +487,7 @@ ThreadSafeArena::ThreadSafeArena(void* mem, size_t size,
ArenaBlock* ThreadSafeArena::FirstBlock(void* buf, size_t size) {
GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(buf) & 7, 0u);
if (buf == nullptr || size <= kBlockHeaderSize) {
return SentryArenaBlock();
return SerialArena::SentryBlock();
}
// Record user-owned block.
alloc_policy_.set_is_user_owned_initial_block(true);
@ -712,7 +702,7 @@ uint64_t ThreadSafeArena::Reset() {
: kBlockHeaderSize + kAllocPolicySize;
first_arena_.Init(new (mem.ptr) ArenaBlock{nullptr, mem.size}, offset);
} else {
first_arena_.Init(SentryArenaBlock(), 0);
first_arena_.Init(SerialArena::SentryBlock(), 0);
}
// Since the first block and potential alloc_policy on the first block is
@ -775,7 +765,7 @@ template <typename Functor>
void ThreadSafeArena::PerConstSerialArenaInChunk(Functor fn) const {
WalkConstSerialArenaChunk([&fn](const SerialArenaChunk* chunk) {
for (const auto& each : chunk->arenas()) {
const SerialArena* serial = each.atomic_get();
const SerialArena* serial = each.relaxed_get();
// It is possible that newly added SerialArena is not updated although
// size was. This is acceptable for SpaceAllocated and SpaceUsed.
if (serial == nullptr) continue;

@ -91,12 +91,14 @@ inline PROTOBUF_ALWAYS_INLINE void* AlignTo(void* p, size_t a) {
// a default memory order (std::memory_order_seq_cst).
template <typename T>
struct Atomic {
PROTOBUF_CONSTEXPR explicit Atomic(T v) : val(v) {}
constexpr explicit Atomic(T v) : val(v) {}
T relaxed_get() const { return val.load(std::memory_order_relaxed); }
T relaxed_get() { return val.load(std::memory_order_relaxed); }
void relaxed_set(T v) { val.store(v, std::memory_order_relaxed); }
T atomic_get() const { return val.load(std::memory_order_acquire); }
T atomic_get() { return val.load(std::memory_order_acquire); }
void atomic_set(T v) { val.store(v, std::memory_order_release); }
T relaxed_fetch_add(T v) {
@ -112,25 +114,28 @@ struct Atomic {
struct ArenaBlock {
// For the sentry block with zero-size where ptr_, limit_, cleanup_nodes all
// point to "this".
PROTOBUF_CONSTEXPR ArenaBlock()
: next(nullptr), cleanup_nodes(this), size(0) {}
constexpr ArenaBlock()
: next(nullptr), cleanup_nodes(this), relaxed_size(0) {}
ArenaBlock(ArenaBlock* next, size_t size)
: next(next), cleanup_nodes(nullptr), size(size) {
: next(next), cleanup_nodes(nullptr), relaxed_size(size) {
GOOGLE_DCHECK_GT(size, sizeof(ArenaBlock));
}
char* Pointer(size_t n) {
GOOGLE_DCHECK_LE(n, size);
GOOGLE_DCHECK_LE(n, size());
return reinterpret_cast<char*>(this) + n;
}
char* Limit() { return Pointer(size & static_cast<size_t>(-8)); }
char* Limit() { return Pointer(size() & static_cast<size_t>(-8)); }
bool IsSentry() const { return size == 0; }
size_t size() const { return relaxed_size.relaxed_get(); }
bool IsSentry() const { return size() == 0; }
ArenaBlock* const next;
void* cleanup_nodes;
const size_t size;
private:
const Atomic<size_t> relaxed_size;
// data follows
};
@ -572,6 +577,13 @@ class PROTOBUF_EXPORT SerialArena {
private:
friend class ThreadSafeArena;
static constexpr ArenaBlock kSentryBlock = {};
static ArenaBlock* SentryBlock() {
// const_cast<> is okay as kSentryBlock will never be mutated.
return const_cast<ArenaBlock*>(&kSentryBlock);
}
// Creates a new SerialArena inside mem using the remaining memory as for
// future allocations.
// The `parent` arena must outlive the serial arena, which is guaranteed
@ -613,6 +625,7 @@ class PROTOBUF_EXPORT SerialArena {
// Helper getters/setters to handle relaxed operations on atomic variables.
ArenaBlock* head() { return head_.relaxed_get(); }
const ArenaBlock* head() const { return head_.relaxed_get(); }
void set_head(ArenaBlock* head) { return head_.relaxed_set(head); }
char* ptr() { return ptr_.relaxed_get(); }
const char* ptr() const { return ptr_.relaxed_get(); }
@ -859,7 +872,7 @@ class PROTOBUF_EXPORT ThreadSafeArena {
#pragma warning(disable : 4324)
#endif
struct alignas(kCacheAlignment) CacheAlignedLifecycleIdGenerator {
PROTOBUF_CONSTEXPR CacheAlignedLifecycleIdGenerator() : id{0} {}
constexpr CacheAlignedLifecycleIdGenerator() : id{0} {}
Atomic<LifecycleIdAtomic> id;
};

@ -244,6 +244,7 @@ cc_test(
":command_line_interface",
":mock_code_generator",
"//:protobuf",
"//src/google/protobuf/compiler/cpp:names",
"//src/google/protobuf:cc_test_protos",
"//src/google/protobuf:test_util2",
"//src/google/protobuf/io",

@ -66,7 +66,7 @@
#include "google/protobuf/compiler/command_line_interface.h"
#include "google/protobuf/compiler/mock_code_generator.h"
#include "google/protobuf/compiler/subprocess.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/compiler/cpp/names.h"
#include "google/protobuf/io/io_win32.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h"

@ -7,6 +7,38 @@ load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("//build_defs:cpp_opts.bzl", "COPTS")
cc_library(
name = "names",
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/cpp",
visibility = ["//visibility:public"],
deps = [
":names_internal",
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf:protobuf_nowkt",
],
)
cc_library(
name = "names_internal",
hdrs = [
"helpers.h",
"names.h",
"options.h",
],
srcs = [
"helpers.cc",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/cpp",
visibility = ["//pkg:__pkg__"],
deps = [
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf:protobuf_nowkt",
],
)
cc_library(
name = "cpp",
srcs = [
@ -16,7 +48,6 @@ cc_library(
"field.cc",
"file.cc",
"generator.cc",
"helpers.cc",
"map_field.cc",
"message.cc",
"message_field.cc",
@ -33,13 +64,10 @@ cc_library(
"field.h",
"file.h",
"generator.h",
"helpers.h",
"map_field.h",
"message.h",
"message_field.h",
"message_layout_helper.h",
"names.h",
"options.h",
"padding_optimizer.h",
"parse_function_generator.h",
"primitive_field.h",
@ -53,6 +81,8 @@ cc_library(
"//src/google/protobuf/compiler:__pkg__",
],
deps = [
":names_internal",
":names",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/base:core_headers",

@ -6,6 +6,19 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("//build_defs:cpp_opts.bzl", "COPTS")
cc_library(
name = "names",
hdrs = ["names.h"],
srcs = ["names.cc"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/csharp",
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf:protobuf_nowkt",
"@com_google_absl//absl/strings",
],
)
cc_library(
name = "csharp",
srcs = [
@ -36,7 +49,6 @@ cc_library(
"csharp_map_field.h",
"csharp_message.h",
"csharp_message_field.h",
"csharp_names.h",
"csharp_options.h",
"csharp_primitive_field.h",
"csharp_reflection_class.h",
@ -56,6 +68,7 @@ cc_library(
"//src/google/protobuf/compiler:__pkg__",
],
deps = [
":names",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/container:flat_hash_set",

@ -38,7 +38,7 @@
#include "google/protobuf/descriptor.h"
#include "google/protobuf/wire_format.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/csharp_names.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/printer.h"

@ -34,9 +34,10 @@
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/compiler/csharp/csharp_names.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/csharp_options.h"
#include "google/protobuf/compiler/csharp/csharp_reflection_class.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h"

@ -47,13 +47,13 @@
#include "google/protobuf/compiler/csharp/csharp_field_base.h"
#include "google/protobuf/compiler/csharp/csharp_map_field.h"
#include "google/protobuf/compiler/csharp/csharp_message_field.h"
#include "google/protobuf/compiler/csharp/csharp_names.h"
#include "google/protobuf/compiler/csharp/csharp_options.h"
#include "google/protobuf/compiler/csharp/csharp_primitive_field.h"
#include "google/protobuf/compiler/csharp/csharp_repeated_enum_field.h"
#include "google/protobuf/compiler/csharp/csharp_repeated_message_field.h"
#include "google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h"
#include "google/protobuf/compiler/csharp/csharp_wrapper_field.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/descriptor.pb.h"
// Must be last.
@ -110,102 +110,6 @@ CSharpType GetCSharpType(FieldDescriptor::Type type) {
return (CSharpType) -1;
}
std::string StripDotProto(const std::string& proto_file) {
int lastindex = proto_file.find_last_of('.');
return proto_file.substr(0, lastindex);
}
std::string GetFileNamespace(const FileDescriptor* descriptor) {
if (descriptor->options().has_csharp_namespace()) {
return descriptor->options().csharp_namespace();
}
return UnderscoresToCamelCase(descriptor->package(), true, true);
}
// Returns the Pascal-cased last part of the proto file. For example,
// input of "google/protobuf/foo_bar.proto" would result in "FooBar".
std::string GetFileNameBase(const FileDescriptor* descriptor) {
std::string proto_file = descriptor->name();
int lastslash = proto_file.find_last_of('/');
std::string base = proto_file.substr(lastslash + 1);
return UnderscoresToPascalCase(StripDotProto(base));
}
std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor) {
// TODO: Detect collisions with existing messages,
// and append an underscore if necessary.
return GetFileNameBase(descriptor) + "Reflection";
}
std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor) {
// TODO: Detect collisions with existing messages,
// and append an underscore if necessary.
return GetFileNameBase(descriptor) + "Extensions";
}
// TODO(jtattermusch): can we reuse a utility function?
std::string UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter,
bool preserve_period) {
std::string result;
// Note: I distrust ctype.h due to locales.
for (int i = 0; i < input.size(); i++) {
if ('a' <= input[i] && input[i] <= 'z') {
if (cap_next_letter) {
result += input[i] + ('A' - 'a');
} else {
result += input[i];
}
cap_next_letter = false;
} else if ('A' <= input[i] && input[i] <= 'Z') {
if (i == 0 && !cap_next_letter) {
// Force first letter to lower-case unless explicitly told to
// capitalize it.
result += input[i] + ('a' - 'A');
} else {
// Capital letters after the first are left as-is.
result += input[i];
}
cap_next_letter = false;
} else if ('0' <= input[i] && input[i] <= '9') {
result += input[i];
cap_next_letter = true;
} else {
cap_next_letter = true;
if (input[i] == '.' && preserve_period) {
result += '.';
}
}
}
// Add a trailing "_" if the name should be altered.
if (input.size() > 0 && input[input.size() - 1] == '#') {
result += '_';
}
// https://github.com/protocolbuffers/protobuf/issues/8101
// To avoid generating invalid identifiers - if the input string
// starts with _<digit> (or multiple underscores then digit) then
// we need to preserve the underscore as an identifier cannot start
// with a digit.
// This check is being done after the loop rather than before
// to handle the case where there are multiple underscores before the
// first digit. We let them all be consumed so we can see if we would
// start with a digit.
// Note: not preserving leading underscores for all otherwise valid identifiers
// so as to not break anything that relies on the existing behaviour
if (result.size() > 0 && ('0' <= result[0] && result[0] <= '9')
&& input.size() > 0 && input[0] == '_')
{
result.insert(0, 1, '_');
}
return result;
}
std::string UnderscoresToPascalCase(const std::string& input) {
return UnderscoresToCamelCase(input, true);
}
// Convert a string which is expected to be SHOUTY_CASE (but may not be *precisely* shouty)
// into a PascalCase string. Precise rules implemented:
@ -342,32 +246,6 @@ uint GetGroupEndTag(const Descriptor* descriptor) {
return 0;
}
std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
std::string result = GetFileNamespace(file);
if (!result.empty()) {
result += '.';
}
std::string classname;
if (file->package().empty()) {
classname = name;
} else {
// Strip the proto package from full_name since we've replaced it with
// the C# namespace.
classname = name.substr(file->package().size() + 1);
}
result += absl::StrReplaceAll(classname, {{".", ".Types."}});
return "global::" + result;
}
std::string GetReflectionClassName(const FileDescriptor* descriptor) {
std::string result = GetFileNamespace(descriptor);
if (!result.empty()) {
result += '.';
}
result += GetReflectionClassUnqualifiedName(descriptor);
return "global::" + result;
}
std::string GetFullExtensionName(const FieldDescriptor* descriptor) {
if (descriptor->extension_scope()) {
return GetClassName(descriptor->extension_scope()) + ".Extensions." + GetPropertyName(descriptor);
@ -377,14 +255,6 @@ std::string GetFullExtensionName(const FieldDescriptor* descriptor) {
}
}
std::string GetClassName(const Descriptor* descriptor) {
return ToCSharpName(descriptor->full_name(), descriptor->file());
}
std::string GetClassName(const EnumDescriptor* descriptor) {
return ToCSharpName(descriptor->full_name(), descriptor->file());
}
// Groups are hacky: The name of the field is just the lower-cased name
// of the group type. In C#, though, we would like to retain the original
// capitalization of the type name.
@ -437,41 +307,6 @@ std::string GetOneofCaseName(const FieldDescriptor* descriptor) {
return property_name == "None" ? "None_" : property_name;
}
std::string GetOutputFile(const FileDescriptor* descriptor,
const std::string file_extension,
const bool generate_directories,
const std::string base_namespace,
std::string* error) {
std::string relative_filename = GetFileNameBase(descriptor) + file_extension;
if (!generate_directories) {
return relative_filename;
}
std::string ns = GetFileNamespace(descriptor);
std::string namespace_suffix = ns;
if (!base_namespace.empty()) {
// Check that the base_namespace is either equal to or a leading part of
// the file namespace. This isn't just a simple prefix; "Foo.B" shouldn't
// be regarded as a prefix of "Foo.Bar". The simplest option is to add "."
// to both.
std::string extended_ns = ns + ".";
if (extended_ns.find(base_namespace + ".") != 0) {
*error = "Namespace " + ns + " is not a prefix namespace of base namespace " + base_namespace;
return ""; // This will be ignored, because we've set an error.
}
namespace_suffix = ns.substr(base_namespace.length());
if (namespace_suffix.find('.') == 0) {
namespace_suffix = namespace_suffix.substr(1);
}
}
std::string namespace_dir =
absl::StrReplaceAll(namespace_suffix, {{".", "/"}});
if (!namespace_dir.empty()) {
namespace_dir += "/";
}
return namespace_dir + relative_filename;
}
// TODO: c&p from Java protoc plugin
// For encodings with fixed sizes, returns that size in bytes. Otherwise
// returns -1.

@ -38,6 +38,7 @@
#include <string>
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/port.h"
#include "google/protobuf/stubs/common.h"
@ -72,15 +73,6 @@ enum CSharpType {
// Converts field type to corresponding C# type.
CSharpType GetCSharpType(FieldDescriptor::Type type);
std::string StripDotProto(const std::string& proto_file);
// Gets unqualified name of the reflection class
std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor);
// Gets unqualified name of the extension class
std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor);
std::string GetClassName(const EnumDescriptor* descriptor);
std::string GetFieldName(const FieldDescriptor* descriptor);
std::string GetFieldConstantName(const FieldDescriptor* field);
@ -91,18 +83,6 @@ std::string GetOneofCaseName(const FieldDescriptor* descriptor);
int GetFixedSize(FieldDescriptor::Type type);
// Note that we wouldn't normally want to export this (we're not expecting
// it to be used outside libprotoc itself) but this exposes it for testing.
std::string PROTOC_EXPORT UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter,
bool preserve_period);
inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) {
return UnderscoresToCamelCase(input, cap_next_letter, false);
}
std::string UnderscoresToPascalCase(const std::string& input);
// Note that we wouldn't normally want to export this (we're not expecting
// it to be used outside libprotoc itself) but this exposes it for testing.
std::string PROTOC_EXPORT GetEnumValueName(const std::string& enum_name,

@ -40,7 +40,7 @@
#include "google/protobuf/compiler/csharp/csharp_enum.h"
#include "google/protobuf/compiler/csharp/csharp_field_base.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/csharp_names.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/compiler/csharp/csharp_options.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"

@ -38,7 +38,7 @@
#include "google/protobuf/compiler/csharp/csharp_field_base.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/csharp_message.h"
#include "google/protobuf/compiler/csharp/csharp_names.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/compiler/csharp/csharp_options.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"

@ -35,7 +35,7 @@
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/csharp_names.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/compiler/csharp/csharp_options.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/printer.h"

@ -0,0 +1,225 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include "google/protobuf/compiler/csharp/names.h"
#include <string>
#include "absl/strings/str_replace.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/descriptor.pb.h"
// Must be last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
namespace {
std::string StripDotProto(const std::string& proto_file) {
int lastindex = proto_file.find_last_of('.');
return proto_file.substr(0, lastindex);
}
// Returns the Pascal-cased last part of the proto file. For example,
// input of "google/protobuf/foo_bar.proto" would result in "FooBar".
std::string GetFileNameBase(const FileDescriptor* descriptor) {
std::string proto_file = descriptor->name();
int lastslash = proto_file.find_last_of('/');
std::string base = proto_file.substr(lastslash + 1);
return UnderscoresToPascalCase(StripDotProto(base));
}
std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
std::string result = GetFileNamespace(file);
if (!result.empty()) {
result += '.';
}
std::string classname;
if (file->package().empty()) {
classname = name;
} else {
// Strip the proto package from full_name since we've replaced it with
// the C# namespace.
classname = name.substr(file->package().size() + 1);
}
result += absl::StrReplaceAll(classname, {{".", ".Types."}});
return "global::" + result;
}
} // namespace
std::string GetFileNamespace(const FileDescriptor* descriptor) {
if (descriptor->options().has_csharp_namespace()) {
return descriptor->options().csharp_namespace();
}
return UnderscoresToCamelCase(descriptor->package(), true, true);
}
std::string GetClassName(const Descriptor* descriptor) {
return ToCSharpName(descriptor->full_name(), descriptor->file());
}
std::string GetClassName(const EnumDescriptor* descriptor) {
return ToCSharpName(descriptor->full_name(), descriptor->file());
}
std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor) {
// TODO: Detect collisions with existing messages,
// and append an underscore if necessary.
return GetFileNameBase(descriptor) + "Reflection";
}
std::string GetReflectionClassName(const FileDescriptor* descriptor) {
std::string result = GetFileNamespace(descriptor);
if (!result.empty()) {
result += '.';
}
result += GetReflectionClassUnqualifiedName(descriptor);
return "global::" + result;
}
std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor) {
// TODO: Detect collisions with existing messages,
// and append an underscore if necessary.
return GetFileNameBase(descriptor) + "Extensions";
}
std::string GetOutputFile(const FileDescriptor* descriptor,
const std::string file_extension,
const bool generate_directories,
const std::string base_namespace,
std::string* error) {
std::string relative_filename = GetFileNameBase(descriptor) + file_extension;
if (!generate_directories) {
return relative_filename;
}
std::string ns = GetFileNamespace(descriptor);
std::string namespace_suffix = ns;
if (!base_namespace.empty()) {
// Check that the base_namespace is either equal to or a leading part of
// the file namespace. This isn't just a simple prefix; "Foo.B" shouldn't
// be regarded as a prefix of "Foo.Bar". The simplest option is to add "."
// to both.
std::string extended_ns = ns + ".";
if (extended_ns.find(base_namespace + ".") != 0) {
*error = "Namespace " + ns + " is not a prefix namespace of base namespace " + base_namespace;
return ""; // This will be ignored, because we've set an error.
}
namespace_suffix = ns.substr(base_namespace.length());
if (namespace_suffix.find('.') == 0) {
namespace_suffix = namespace_suffix.substr(1);
}
}
std::string namespace_dir =
absl::StrReplaceAll(namespace_suffix, {{".", "/"}});
if (!namespace_dir.empty()) {
namespace_dir += "/";
}
return namespace_dir + relative_filename;
}
std::string UnderscoresToPascalCase(const std::string& input) {
return UnderscoresToCamelCase(input, true);
}
// TODO(jtattermusch): can we reuse a utility function?
std::string UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter,
bool preserve_period) {
std::string result;
// Note: I distrust ctype.h due to locales.
for (int i = 0; i < input.size(); i++) {
if ('a' <= input[i] && input[i] <= 'z') {
if (cap_next_letter) {
result += input[i] + ('A' - 'a');
} else {
result += input[i];
}
cap_next_letter = false;
} else if ('A' <= input[i] && input[i] <= 'Z') {
if (i == 0 && !cap_next_letter) {
// Force first letter to lower-case unless explicitly told to
// capitalize it.
result += input[i] + ('a' - 'A');
} else {
// Capital letters after the first are left as-is.
result += input[i];
}
cap_next_letter = false;
} else if ('0' <= input[i] && input[i] <= '9') {
result += input[i];
cap_next_letter = true;
} else {
cap_next_letter = true;
if (input[i] == '.' && preserve_period) {
result += '.';
}
}
}
// Add a trailing "_" if the name should be altered.
if (input.size() > 0 && input[input.size() - 1] == '#') {
result += '_';
}
// https://github.com/protocolbuffers/protobuf/issues/8101
// To avoid generating invalid identifiers - if the input string
// starts with _<digit> (or multiple underscores then digit) then
// we need to preserve the underscore as an identifier cannot start
// with a digit.
// This check is being done after the loop rather than before
// to handle the case where there are multiple underscores before the
// first digit. We let them all be consumed so we can see if we would
// start with a digit.
// Note: not preserving leading underscores for all otherwise valid identifiers
// so as to not break anything that relies on the existing behaviour
if (result.size() > 0 && ('0' <= result[0] && result[0] <= '9')
&& input.size() > 0 && input[0] == '_')
{
result.insert(0, 1, '_');
}
return result;
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"

@ -71,9 +71,35 @@ std::string PROTOC_EXPORT GetClassName(const Descriptor* descriptor);
// descriptor != NULL
//
// Returns:
// The fully-qualified name of the C# class that provides
// access to the file descriptor. Proto compiler generates
// The fully-qualified C# enum class name.
std::string GetClassName(const EnumDescriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The unqualified name of the C# class that provides access to the file
// descriptor. Proto compiler generates
// such class for each .proto file processed.
std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor);
// Gets unqualified name of the extension class
// Requires:
// descriptor != NULL
//
// Returns:
// The unqualified name of the generated C# extensions class that provide
// access to extensions. Proto compiler generates such class for each
// .proto file processed that contains extensions.
std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified name of the C# class that provides access to the file
// descriptor. Proto compiler generates such class for each .proto file
// processed.
std::string PROTOC_EXPORT
GetReflectionClassName(const FileDescriptor* descriptor);
@ -97,6 +123,18 @@ std::string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor,
const std::string base_namespace,
std::string* error);
std::string UnderscoresToPascalCase(const std::string& input);
// Note that we wouldn't normally want to export this (we're not expecting
// it to be used outside libprotoc itself) but this exposes it for testing.
std::string PROTOC_EXPORT UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter,
bool preserve_period);
inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) {
return UnderscoresToCamelCase(input, cap_next_letter, false);
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf

@ -6,6 +6,41 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("//build_defs:cpp_opts.bzl", "COPTS")
cc_library(
name = "names",
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/java",
visibility = ["//visibility:public"],
deps = [
":names_internal",
"//src/google/protobuf:protobuf_nowkt",
],
)
cc_library(
name = "names_internal",
hdrs = [
"helpers.h",
"name_resolver.h",
"names.h",
"options.h",
],
srcs = [
"helpers.cc",
"name_resolver.cc",
"names.cc",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/java",
visibility = ["//pkg:__pkg__"],
deps = [
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf:protobuf_nowkt",
"@com_google_absl//absl/container:flat_hash_set",
],
)
cc_library(
name = "java",
srcs = [
@ -21,7 +56,6 @@ cc_library(
"file.cc",
"generator.cc",
"generator_factory.cc",
"helpers.cc",
"kotlin_generator.cc",
"map_field.cc",
"map_field_lite.cc",
@ -32,7 +66,6 @@ cc_library(
"message_field_lite.cc",
"message_lite.cc",
"message_serialization.cc",
"name_resolver.cc",
"primitive_field.cc",
"primitive_field_lite.cc",
"service.cc",
@ -53,7 +86,6 @@ cc_library(
"file.h",
"generator.h",
"generator_factory.h",
"helpers.h",
"kotlin_generator.h",
"map_field.h",
"map_field_lite.h",
@ -64,9 +96,6 @@ cc_library(
"message_field_lite.h",
"message_lite.h",
"message_serialization.h",
"name_resolver.h",
"names.h",
"options.h",
"primitive_field.h",
"primitive_field_lite.h",
"service.h",
@ -81,6 +110,8 @@ cc_library(
"//src/google/protobuf/compiler:__pkg__",
],
deps = [
":names_internal",
":names",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/container:flat_hash_set",

@ -131,10 +131,10 @@ void Context::InitializeFieldGeneratorInfoForFields(
std::vector<std::string> conflict_reason(fields.size());
for (int i = 0; i < fields.size(); ++i) {
const FieldDescriptor* field = fields[i];
const std::string& name = UnderscoresToCapitalizedCamelCase(field);
const std::string& name = CapitalizedFieldName(field);
for (int j = i + 1; j < fields.size(); ++j) {
const FieldDescriptor* other = fields[j];
const std::string& other_name = UnderscoresToCapitalizedCamelCase(other);
const std::string& other_name = CapitalizedFieldName(other);
if (name == other_name) {
is_conflict[i] = is_conflict[j] = true;
conflict_reason[i] = conflict_reason[j] =
@ -155,7 +155,7 @@ void Context::InitializeFieldGeneratorInfoForFields(
const FieldDescriptor* field = fields[i];
FieldGeneratorInfo info;
info.name = CamelCaseFieldName(field);
info.capitalized_name = UnderscoresToCapitalizedCamelCase(field);
info.capitalized_name = CapitalizedFieldName(field);
// For fields conflicting with some other fields, we append the field
// number to their field names in generated code to avoid conflicts.
if (is_conflict[i]) {

@ -35,6 +35,7 @@
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/options.h"
#include "google/protobuf/port.h"
@ -106,6 +107,20 @@ class Context {
Options options_;
};
template <typename Descriptor>
void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer,
Descriptor* descriptor, bool immutable,
const std::string& suffix = "") {
if (IsOwnFile(descriptor, immutable)) {
PrintGeneratedAnnotation(printer, '$',
context->options().annotate_code
? AnnotationFileName(descriptor, suffix)
: "",
context->options());
}
}
} // namespace java
} // namespace compiler
} // namespace protobuf

@ -280,7 +280,7 @@ void ImmutableEnumFieldGenerator::GenerateKotlinDslMembers(
if (SupportUnknownEnumValue(descriptor_->file())) {
printer->Print(
variables_,
"$kt_deprecation$ var $kt_name$Value: kotlin.Int\n"
"$kt_deprecation$public var $kt_name$Value: kotlin.Int\n"
" @JvmName(\"${$get$kt_capitalized_name$Value$}$\")\n"
" get() = $kt_dsl_builder$.${$get$capitalized_name$Value$}$()\n"
" @JvmName(\"${$set$kt_capitalized_name$Value$}$\")\n"
@ -533,7 +533,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
void ImmutableEnumOneofFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
// Enum fields in oneofs are correctly cleared by clearing the oneof
// No-op: Enum fields in oneofs are correctly cleared by clearing the oneof
}
void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode(

@ -329,7 +329,7 @@ void ImmutableEnumFieldLiteGenerator::GenerateKotlinDslMembers(
if (SupportUnknownEnumValue(descriptor_->file())) {
printer->Print(
variables_,
"$kt_deprecation$ var $kt_name$Value: kotlin.Int\n"
"$kt_deprecation$public var $kt_name$Value: kotlin.Int\n"
" @JvmName(\"${$get$kt_capitalized_name$Value$}$\")\n"
" get() = $kt_dsl_builder$.${$get$capitalized_name$Value$}$()\n"
" @JvmName(\"${$set$kt_capitalized_name$Value$}$\")\n"

@ -51,7 +51,6 @@
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "google/protobuf/compiler/java/name_resolver.h"
#include "google/protobuf/compiler/java/names.h"
#include "google/protobuf/descriptor.pb.h"
// Must be last.
@ -70,75 +69,6 @@ const char kThickSeparator[] =
const char kThinSeparator[] =
"// -------------------------------------------------------------------\n";
namespace {
const char* DefaultPackage(Options options) {
return options.opensource_runtime ? "" : "com.google.protos";
}
bool IsReservedName(absl::string_view name) {
static const auto& kReservedNames =
*new absl::flat_hash_set<absl::string_view>({
"abstract", "assert", "boolean", "break", "byte",
"case", "catch", "char", "class", "const",
"continue", "default", "do", "double", "else",
"enum", "extends", "final", "finally", "float",
"for", "goto", "if", "implements", "import",
"instanceof", "int", "interface", "long", "native",
"new", "package", "private", "protected", "public",
"return", "short", "static", "strictfp", "super",
"switch", "synchronized", "this", "throw", "throws",
"transient", "try", "void", "volatile", "while",
});
return kReservedNames.contains(name);
}
bool IsForbidden(const std::string& field_name) {
// Names that should be avoided (in UpperCamelCase format).
// Using them will cause the compiler to generate accessors whose names
// collide with methods defined in base classes.
// Keep this list in sync with specialFieldNames in
// java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java
static const auto& kForbiddenNames =
*new absl::flat_hash_set<absl::string_view>({
// java.lang.Object:
"Class",
// com.google.protobuf.MessageLiteOrBuilder:
"DefaultInstanceForType",
// com.google.protobuf.MessageLite:
"ParserForType",
"SerializedSize",
// com.google.protobuf.MessageOrBuilder:
"AllFields",
"DescriptorForType",
"InitializationErrorString",
"UnknownFields",
// obsolete. kept for backwards compatibility of generated code
"CachedSize",
});
return kForbiddenNames.contains(UnderscoresToCamelCase(field_name, true));
}
std::string FieldName(const FieldDescriptor* field) {
std::string field_name;
// Groups are hacky: The name of the field is just the lower-cased name
// of the group type. In Java, though, we would like to retain the original
// capitalization of the type name.
if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
field_name = field->message_type()->name();
} else {
field_name = field->name();
}
if (IsForbidden(field_name)) {
// Append a trailing "#" to indicate that the name should be decorated to
// avoid collision with other names.
field_name += "#";
}
return field_name;
}
} // namespace
void PrintGeneratedAnnotation(io::Printer* printer, char delimiter,
const std::string& annotation_file,
Options options) {
@ -236,30 +166,6 @@ std::string ToCamelCase(const std::string& input, bool lower_first) {
return result;
}
std::string UnderscoresToCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCase(FieldName(field), false);
}
std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCase(FieldName(field), true);
}
std::string CapitalizedFieldName(const FieldDescriptor* field) {
return UnderscoresToCapitalizedCamelCase(field);
}
std::string UnderscoresToCamelCase(const MethodDescriptor* method) {
return UnderscoresToCamelCase(method->name(), false);
}
std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) {
std::string name = UnderscoresToCamelCase(field);
if (IsReservedName(name)) {
return name + "_";
}
return name;
}
// Names that should be avoided as field names in Kotlin.
// All Kotlin hard keywords are in this list.
bool IsForbiddenKotlin(absl::string_view field_name) {
@ -305,54 +211,12 @@ std::string FileClassName(const FileDescriptor* file, bool immutable) {
return ClassNameResolver().GetFileClassName(file, immutable);
}
std::string FileJavaPackage(const FileDescriptor* file, bool immutable,
Options options) {
std::string result;
if (file->options().has_java_package()) {
result = file->options().java_package();
} else {
result = DefaultPackage(options);
if (!file->package().empty()) {
if (!result.empty()) result += '.';
result += file->package();
}
}
return result;
}
std::string FileJavaPackage(const FileDescriptor* file, Options options) {
return FileJavaPackage(file, true /* immutable */, options);
}
std::string JavaPackageToDir(std::string package_name) {
std::string package_dir = absl::StrReplaceAll(package_name, {{".", "/"}});
if (!package_dir.empty()) package_dir += "/";
return package_dir;
}
std::string ClassName(const Descriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string ClassName(const EnumDescriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string ClassName(const ServiceDescriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string ClassName(const FileDescriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string ExtraMessageInterfaces(const Descriptor* descriptor) {
std::string interfaces = "// @@protoc_insertion_point(message_implements:" +
descriptor->full_name() + ")";

@ -41,7 +41,7 @@
#include "google/protobuf/io/printer.h"
#include "google/protobuf/descriptor.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/java/context.h"
#include "google/protobuf/compiler/java/names.h"
#include "google/protobuf/compiler/java/options.h"
#include "google/protobuf/descriptor.pb.h"
@ -84,22 +84,6 @@ void PrintEnumVerifierLogic(io::Printer* printer,
// first letter.
std::string ToCamelCase(const std::string& input, bool lower_first);
// Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter.
std::string UnderscoresToCamelCase(const std::string& name,
bool cap_first_letter);
// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
// "fooBarBaz" or "FooBarBaz", respectively.
std::string UnderscoresToCamelCase(const FieldDescriptor* field);
std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
// Similar, but for method names. (Typically, this merely has the effect
// of lower-casing the first letter of the name.)
std::string UnderscoresToCamelCase(const MethodDescriptor* method);
// Same as UnderscoresToCamelCase, but checks for reserved keywords
std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field);
// Similar to UnderscoresToCamelCase, but guarantees that the result is a
// complete Java identifier by adding a _ if needed.
std::string CamelCaseFieldName(const FieldDescriptor* field);
@ -205,19 +189,6 @@ std::string AnnotationFileName(const Descriptor* descriptor,
return descriptor->name() + suffix + ".java.pb.meta";
}
template <typename Descriptor>
void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer,
Descriptor* descriptor, bool immutable,
const std::string& suffix = "") {
if (IsOwnFile(descriptor, immutable)) {
PrintGeneratedAnnotation(printer, '$',
context->options().annotate_code
? AnnotationFileName(descriptor, suffix)
: "",
context->options());
}
}
// Get the unqualified name that should be used for a field's field
// number constant.
std::string FieldConstantName(const FieldDescriptor* field);

@ -1372,7 +1372,7 @@ void ImmutableMessageGenerator::GenerateKotlinOrNull(io::Printer* printer) const
const FieldDescriptor* field = descriptor_->field(i);
if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) {
printer->Print(
"val $full_classname$OrBuilder.$camelcase_name$OrNull: $full_name$?\n"
"public val $full_classname$OrBuilder.$camelcase_name$OrNull: $full_name$?\n"
" get() = if (has$name$()) get$name$() else null\n\n",
"full_classname",
EscapeKotlinKeywords(name_resolver_->GetClassName(descriptor_, true)),

@ -295,6 +295,9 @@ void MessageBuilderGenerator::GenerateDescriptorMethods(io::Printer* printer) {
void MessageBuilderGenerator::GenerateCommonBuilderMethods(
io::Printer* printer) {
// Decide if we really need to have the "maybeForceBuilderInitialization()"
// method.
// TODO(b/249158148): Remove the need for this entirely
bool need_maybe_force_builder_init = false;
for (int i = 0; i < descriptor_->field_count(); i++) {
if (descriptor_->field(i)->message_type() != nullptr &&

@ -870,7 +870,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) c
const FieldDescriptor* field = descriptor_->field(i);
if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) {
printer->Print(
"val $full_classname$OrBuilder.$camelcase_name$OrNull: "
"public val $full_classname$OrBuilder.$camelcase_name$OrNull: "
"$full_name$?\n"
" get() = if (has$name$()) get$name$() else null\n\n",
"full_classname",

@ -0,0 +1,193 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include "google/protobuf/compiler/java/names.h"
#include <string>
#include "absl/container/flat_hash_set.h"
#include "google/protobuf/compiler/java/helpers.h"
#include "google/protobuf/compiler/java/name_resolver.h"
#include "google/protobuf/compiler/java/names.h"
#include "google/protobuf/compiler/java/options.h"
#include "google/protobuf/descriptor.pb.h"
// Must be last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
namespace {
const char* DefaultPackage(Options options) {
return options.opensource_runtime ? "" : "com.google.protos";
}
bool IsReservedName(absl::string_view name) {
static const auto& kReservedNames =
*new absl::flat_hash_set<absl::string_view>({
"abstract", "assert", "boolean", "break", "byte",
"case", "catch", "char", "class", "const",
"continue", "default", "do", "double", "else",
"enum", "extends", "final", "finally", "float",
"for", "goto", "if", "implements", "import",
"instanceof", "int", "interface", "long", "native",
"new", "package", "private", "protected", "public",
"return", "short", "static", "strictfp", "super",
"switch", "synchronized", "this", "throw", "throws",
"transient", "try", "void", "volatile", "while",
});
return kReservedNames.contains(name);
}
bool IsForbidden(const std::string& field_name) {
// Names that should be avoided (in UpperCamelCase format).
// Using them will cause the compiler to generate accessors whose names
// collide with methods defined in base classes.
// Keep this list in sync with specialFieldNames in
// java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java
static const auto& kForbiddenNames =
*new absl::flat_hash_set<absl::string_view>({
// java.lang.Object:
"Class",
// com.google.protobuf.MessageLiteOrBuilder:
"DefaultInstanceForType",
// com.google.protobuf.MessageLite:
"ParserForType",
"SerializedSize",
// com.google.protobuf.MessageOrBuilder:
"AllFields",
"DescriptorForType",
"InitializationErrorString",
"UnknownFields",
// obsolete. kept for backwards compatibility of generated code
"CachedSize",
});
return kForbiddenNames.contains(UnderscoresToCamelCase(field_name, true));
}
std::string FieldName(const FieldDescriptor* field) {
std::string field_name;
// Groups are hacky: The name of the field is just the lower-cased name
// of the group type. In Java, though, we would like to retain the original
// capitalization of the type name.
if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
field_name = field->message_type()->name();
} else {
field_name = field->name();
}
if (IsForbidden(field_name)) {
// Append a trailing "#" to indicate that the name should be decorated to
// avoid collision with other names.
field_name += "#";
}
return field_name;
}
} // namespace
std::string ClassName(const Descriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string ClassName(const EnumDescriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string ClassName(const ServiceDescriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string ClassName(const FileDescriptor* descriptor) {
ClassNameResolver name_resolver;
return name_resolver.GetClassName(descriptor, true);
}
std::string FileJavaPackage(const FileDescriptor* file, bool immutable,
Options options) {
std::string result;
if (file->options().has_java_package()) {
result = file->options().java_package();
} else {
result = DefaultPackage(options);
if (!file->package().empty()) {
if (!result.empty()) result += '.';
result += file->package();
}
}
return result;
}
std::string FileJavaPackage(const FileDescriptor* file, Options options) {
return FileJavaPackage(file, true /* immutable */, options);
}
std::string CapitalizedFieldName(const FieldDescriptor* field) {
return UnderscoresToCamelCase(FieldName(field), true);
}
std::string UnderscoresToCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCase(FieldName(field), false);
}
std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCase(FieldName(field), true);
}
std::string UnderscoresToCamelCase(const MethodDescriptor* method) {
return UnderscoresToCamelCase(method->name(), false);
}
std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) {
std::string name = UnderscoresToCamelCase(field);
if (IsReservedName(name)) {
return name + "_";
}
return name;
}
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"

@ -40,8 +40,12 @@
#include <string>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/compiler/java/options.h"
// Must be last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@ -96,8 +100,36 @@ std::string FileJavaPackage(const FileDescriptor* descriptor,
// Capitalized camel case name field name.
std::string CapitalizedFieldName(const FieldDescriptor* descriptor);
// Returns:
// Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter.
std::string UnderscoresToCamelCase(const std::string& name,
bool cap_first_letter);
// Requires:
// field != NULL
// Returns:
// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
// "fooBarBaz" or "FooBarBaz", respectively.
std::string UnderscoresToCamelCase(const FieldDescriptor* field);
// Requires:
// method != NULL
// Returns:
// Similar, but for method names. (Typically, this merely has the effect
// of lower-casing the first letter of the name.)
std::string UnderscoresToCamelCase(const MethodDescriptor* method);
// Requires:
// field != NULL
// Returns:
// Same as UnderscoresToCamelCase, but checks for reserved keywords
std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field);
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__

@ -609,7 +609,8 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers(
void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
// When a primitive field is in a oneof, clearing the oneof clears that field.
// No-Op: When a primitive field is in a oneof, clearing the oneof clears that
// field.
}
void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode(

@ -688,7 +688,7 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers(
void ImmutableStringOneofFieldGenerator::GenerateBuilderClearCode(
io::Printer* printer) const {
// String fields in oneofs are correctly cleared by clearing the oneof
// No-Op: String fields in oneofs are correctly cleared by clearing the oneof
}
void ImmutableStringOneofFieldGenerator::GenerateMergingCode(

@ -6,6 +6,35 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("//build_defs:cpp_opts.bzl", "COPTS")
cc_library(
name = "names",
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/objectivec",
visibility = ["//visibility:public"],
deps = [
":names_internal",
],
)
cc_library(
name = "names_internal",
hdrs = [
"names.h",
"objectivec_nsobject_methods.h",
],
srcs = [
"names.cc",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/objectivec",
visibility = ["//pkg:__pkg__"],
deps = [
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf:protobuf_nowkt",
],
)
cc_library(
name = "objectivec",
srcs = [
@ -15,7 +44,6 @@ cc_library(
"objectivec_field.cc",
"objectivec_file.cc",
"objectivec_generator.cc",
"objectivec_helpers.cc",
"objectivec_map_field.cc",
"objectivec_message.cc",
"objectivec_message_field.cc",
@ -33,7 +61,6 @@ cc_library(
"objectivec_map_field.h",
"objectivec_message.h",
"objectivec_message_field.h",
"objectivec_nsobject_methods.h",
"objectivec_oneof.h",
"objectivec_options.h",
"objectivec_primitive_field.h",
@ -45,6 +72,7 @@ cc_library(
"//src/google/protobuf/compiler:__pkg__",
],
deps = [
":names",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/strings",

@ -49,7 +49,7 @@
#include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h"
#include "absl/strings/strip.h"
#include "google/protobuf/compiler/objectivec/objectivec_helpers.h"
#include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/coded_stream.h"

@ -0,0 +1,363 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Helper functions for generating ObjectiveC code.
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_NAMES_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_NAMES_H__
#include <string>
#include <vector>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/zero_copy_stream.h"
// clang-format off
#include "google/protobuf/port_def.inc"
// clang-format on
namespace google {
namespace protobuf {
namespace compiler {
namespace objectivec {
// Get/Set the path to a file to load for objc class prefix lookups.
std::string PROTOC_EXPORT GetPackageToPrefixMappingsPath();
void PROTOC_EXPORT SetPackageToPrefixMappingsPath(
const std::string& file_path);
// Get/Set if the proto package should be used to make the default prefix for
// symbols. This will then impact most of the type naming apis below. It is done
// as a global to not break any other generator reusing the methods since they
// are exported.
bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix();
void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off);
// Get/Set the path to a file to load as exceptions when
// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there
// should be no exceptions.
std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList();
void PROTOC_EXPORT SetProtoPackagePrefixExceptionList(
const std::string& file_path);
// Get/Set a prefix to add before the prefix generated from the package name.
// This is only used when UseProtoPackageAsDefaultPrefix() is True.
std::string PROTOC_EXPORT GetForcedPackagePrefix();
void PROTOC_EXPORT SetForcedPackagePrefix(const std::string& prefix);
// Generator Prefix Validation Options (see objectivec_generator.cc for a
// description of each):
struct Options {
Options();
std::string expected_prefixes_path;
std::vector<std::string> expected_prefixes_suppressions;
bool prefixes_must_be_registered;
bool require_prefixes;
};
// Escape C++ trigraphs by escaping question marks to "\?".
std::string PROTOC_EXPORT EscapeTrigraphs(absl::string_view to_escape);
// Remove white space from either end of a absl::string_view.
void PROTOC_EXPORT TrimWhitespace(absl::string_view* input);
// Returns true if the name requires a ns_returns_not_retained attribute applied
// to it.
bool PROTOC_EXPORT IsRetainedName(const std::string& name);
// Returns true if the name starts with "init" and will need to have special
// handling under ARC.
bool PROTOC_EXPORT IsInitName(const std::string& name);
// Returns true if the name requires a cf_returns_not_retained attribute applied
// to it.
bool PROTOC_EXPORT IsCreateName(const std::string& name);
// Gets the objc_class_prefix or the prefix made from the proto package.
std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file);
// Gets the path of the file we're going to generate (sans the .pb.h
// extension). The path will be dependent on the objectivec package
// declared in the proto package.
std::string PROTOC_EXPORT FilePath(const FileDescriptor* file);
// Just like FilePath(), but without the directory part.
std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file);
// Gets the name of the root class we'll generate in the file. This class
// is not meant for external consumption, but instead contains helpers that
// the rest of the classes need
std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
// descriptor.
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
std::string* out_suffix_added);
std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
// Returns the fully-qualified name of the enum value corresponding to the
// the descriptor.
std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
// Returns the name of the enum value corresponding to the descriptor.
std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
// Reverse what an enum does.
std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name);
// Returns the name to use for the extension (used as the method off the file's
// Root class).
std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
// Returns the transformed field name.
std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
// Returns the transformed oneof name.
std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
// Returns a symbol that can be used in C code to refer to an Objective C
// class without initializing the class.
std::string PROTOC_EXPORT ObjCClass(const std::string& class_name);
// Declares an Objective C class without initializing the class so that it can
// be refrerred to by ObjCClass.
std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name);
inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
}
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
return descriptor->options().map_entry();
}
// Reverse of the above.
std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name,
const FieldDescriptor* field);
enum ObjectiveCType {
OBJECTIVECTYPE_INT32,
OBJECTIVECTYPE_UINT32,
OBJECTIVECTYPE_INT64,
OBJECTIVECTYPE_UINT64,
OBJECTIVECTYPE_FLOAT,
OBJECTIVECTYPE_DOUBLE,
OBJECTIVECTYPE_BOOLEAN,
OBJECTIVECTYPE_STRING,
OBJECTIVECTYPE_DATA,
OBJECTIVECTYPE_ENUM,
OBJECTIVECTYPE_MESSAGE
};
enum FlagType {
FLAGTYPE_DESCRIPTOR_INITIALIZATION,
FLAGTYPE_EXTENSION,
FLAGTYPE_FIELD
};
template <class TDescriptor>
std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
const FileDescriptor* file = NULL,
bool preSpace = true,
bool postNewline = false) {
bool isDeprecated = descriptor->options().deprecated();
// The file is only passed when checking Messages & Enums, so those types
// get tagged. At the moment, it doesn't seem to make sense to tag every
// field or enum value with when the file is deprecated.
bool isFileLevelDeprecation = false;
if (!isDeprecated && file) {
isFileLevelDeprecation = file->options().deprecated();
isDeprecated = isFileLevelDeprecation;
}
if (isDeprecated) {
std::string message;
const FileDescriptor* sourceFile = descriptor->file();
if (isFileLevelDeprecation) {
message = sourceFile->name() + " is deprecated.";
} else {
message = descriptor->full_name() + " is deprecated (see " +
sourceFile->name() + ").";
}
std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")";
if (preSpace) {
result.insert(0, " ");
}
if (postNewline) {
result.append("\n");
}
return result;
} else {
return "";
}
}
std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field);
ObjectiveCType PROTOC_EXPORT
GetObjectiveCType(FieldDescriptor::Type field_type);
inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
return GetObjectiveCType(field->type());
}
bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field);
bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field);
std::string PROTOC_EXPORT
GPBGenericValueFieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field);
std::string PROTOC_EXPORT
BuildFlagsString(const FlagType type, const std::vector<std::string>& strings);
// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
// file.
std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location,
bool prefer_single_line);
// The name the commonly used by the library when built as a framework.
// This lines up to the name used in the CocoaPod.
extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName;
// Returns the CPP symbol name to use as the gate for framework style imports
// for the given framework name to use.
std::string PROTOC_EXPORT
ProtobufFrameworkImportSymbol(const std::string& framework_name);
// Checks if the file is one of the proto's bundled with the library.
bool PROTOC_EXPORT
IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
// Checks the prefix for the given files and outputs any warnings as needed. If
// there are flat out errors, then out_error is filled in with the first error
// and the result is false.
bool PROTOC_EXPORT ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files,
const Options& validation_options, std::string* out_error);
// Same was the other ValidateObjCClassPrefixes() calls, but the options all
// come from the environment variables.
bool PROTOC_EXPORT ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files, std::string* out_error);
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
// the input into the expected output.
class PROTOC_EXPORT TextFormatDecodeData {
public:
TextFormatDecodeData();
~TextFormatDecodeData();
TextFormatDecodeData(const TextFormatDecodeData&) = delete;
TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
void AddString(int32_t key, const std::string& input_for_decode,
const std::string& desired_output);
size_t num_entries() const { return entries_.size(); }
std::string Data() const;
static std::string DecodeDataForString(const std::string& input_for_decode,
const std::string& desired_output);
private:
typedef std::pair<int32_t, std::string> DataEntry;
std::vector<DataEntry> entries_;
};
// Helper for parsing simple files.
class PROTOC_EXPORT LineConsumer {
public:
LineConsumer();
virtual ~LineConsumer();
virtual bool ConsumeLine(const absl::string_view& line, std::string* out_error) = 0;
};
bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,
LineConsumer* line_consumer,
std::string* out_error);
bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
const std::string& stream_name,
LineConsumer* line_consumer,
std::string* out_error);
// Helper class for parsing framework import mappings and generating
// import statements.
class PROTOC_EXPORT ImportWriter {
public:
ImportWriter(const std::string& generate_for_named_framework,
const std::string& named_framework_to_proto_path_mappings_path,
const std::string& runtime_import_prefix,
bool include_wkt_imports);
~ImportWriter();
void AddFile(const FileDescriptor* file, const std::string& header_extension);
void Print(io::Printer* printer) const;
static void PrintRuntimeImports(io::Printer* printer,
const std::vector<std::string>& header_to_import,
const std::string& runtime_import_prefix,
bool default_cpp_symbol = false);
private:
class ProtoFrameworkCollector : public LineConsumer {
public:
ProtoFrameworkCollector(std::map<std::string, std::string>* inout_proto_file_to_framework_name)
: map_(inout_proto_file_to_framework_name) {}
virtual bool ConsumeLine(const absl::string_view& line, std::string* out_error) override;
private:
std::map<std::string, std::string>* map_;
};
void ParseFrameworkMappings();
const std::string generate_for_named_framework_;
const std::string named_framework_to_proto_path_mappings_path_;
const std::string runtime_import_prefix_;
const bool include_wkt_imports_;
std::map<std::string, std::string> proto_file_to_framework_name_;
bool need_to_parse_mapping_file_;
std::vector<std::string> protobuf_imports_;
std::vector<std::string> other_framework_imports_;
std::vector<std::string> other_imports_;
};
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_NAMES_H__

@ -33,12 +33,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
#include <string>
#include <vector>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "google/protobuf/compiler/objectivec/names.h"
// clang-format off
#include "google/protobuf/port_def.inc"
@ -49,309 +44,8 @@ namespace protobuf {
namespace compiler {
namespace objectivec {
// Get/Set the path to a file to load for objc class prefix lookups.
std::string PROTOC_EXPORT GetPackageToPrefixMappingsPath();
void PROTOC_EXPORT SetPackageToPrefixMappingsPath(
const std::string& file_path);
// Get/Set if the proto package should be used to make the default prefix for
// symbols. This will then impact most of the type naming apis below. It is done
// as a global to not break any other generator reusing the methods since they
// are exported.
bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix();
void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off);
// Get/Set the path to a file to load as exceptions when
// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there
// should be no exceptions.
std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList();
void PROTOC_EXPORT SetProtoPackagePrefixExceptionList(
const std::string& file_path);
// Get/Set a prefix to add before the prefix generated from the package name.
// This is only used when UseProtoPackageAsDefaultPrefix() is True.
std::string PROTOC_EXPORT GetForcedPackagePrefix();
void PROTOC_EXPORT SetForcedPackagePrefix(const std::string& prefix);
// Generator Prefix Validation Options (see objectivec_generator.cc for a
// description of each):
struct Options {
Options();
std::string expected_prefixes_path;
std::vector<std::string> expected_prefixes_suppressions;
bool prefixes_must_be_registered;
bool require_prefixes;
};
// Escape C++ trigraphs by escaping question marks to "\?".
std::string PROTOC_EXPORT EscapeTrigraphs(absl::string_view to_escape);
// Remove white space from either end of a absl::string_view.
void PROTOC_EXPORT TrimWhitespace(absl::string_view* input);
// Returns true if the name requires a ns_returns_not_retained attribute applied
// to it.
bool PROTOC_EXPORT IsRetainedName(const std::string& name);
// Returns true if the name starts with "init" and will need to have special
// handling under ARC.
bool PROTOC_EXPORT IsInitName(const std::string& name);
// Returns true if the name requires a cf_returns_not_retained attribute applied
// to it.
bool PROTOC_EXPORT IsCreateName(const std::string& name);
// Gets the objc_class_prefix or the prefix made from the proto package.
std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file);
// Gets the path of the file we're going to generate (sans the .pb.h
// extension). The path will be dependent on the objectivec package
// declared in the proto package.
std::string PROTOC_EXPORT FilePath(const FileDescriptor* file);
// Just like FilePath(), but without the directory part.
std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file);
// Gets the name of the root class we'll generate in the file. This class
// is not meant for external consumption, but instead contains helpers that
// the rest of the classes need
std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
// descriptor.
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
std::string* out_suffix_added);
std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
// Returns the fully-qualified name of the enum value corresponding to the
// the descriptor.
std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
// Returns the name of the enum value corresponding to the descriptor.
std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
// Reverse what an enum does.
std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name);
// Returns the name to use for the extension (used as the method off the file's
// Root class).
std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
// Returns the transformed field name.
std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
// Returns the transformed oneof name.
std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
// Returns a symbol that can be used in C code to refer to an Objective C
// class without initializing the class.
std::string PROTOC_EXPORT ObjCClass(const std::string& class_name);
// Declares an Objective C class without initializing the class so that it can
// be refrerred to by ObjCClass.
std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name);
inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
}
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
return descriptor->options().map_entry();
}
// Reverse of the above.
std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name,
const FieldDescriptor* field);
enum ObjectiveCType {
OBJECTIVECTYPE_INT32,
OBJECTIVECTYPE_UINT32,
OBJECTIVECTYPE_INT64,
OBJECTIVECTYPE_UINT64,
OBJECTIVECTYPE_FLOAT,
OBJECTIVECTYPE_DOUBLE,
OBJECTIVECTYPE_BOOLEAN,
OBJECTIVECTYPE_STRING,
OBJECTIVECTYPE_DATA,
OBJECTIVECTYPE_ENUM,
OBJECTIVECTYPE_MESSAGE
};
enum FlagType {
FLAGTYPE_DESCRIPTOR_INITIALIZATION,
FLAGTYPE_EXTENSION,
FLAGTYPE_FIELD
};
template <class TDescriptor>
std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
const FileDescriptor* file = NULL,
bool preSpace = true,
bool postNewline = false) {
bool isDeprecated = descriptor->options().deprecated();
// The file is only passed when checking Messages & Enums, so those types
// get tagged. At the moment, it doesn't seem to make sense to tag every
// field or enum value with when the file is deprecated.
bool isFileLevelDeprecation = false;
if (!isDeprecated && file) {
isFileLevelDeprecation = file->options().deprecated();
isDeprecated = isFileLevelDeprecation;
}
if (isDeprecated) {
std::string message;
const FileDescriptor* sourceFile = descriptor->file();
if (isFileLevelDeprecation) {
message = sourceFile->name() + " is deprecated.";
} else {
message = descriptor->full_name() + " is deprecated (see " +
sourceFile->name() + ").";
}
std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")";
if (preSpace) {
result.insert(0, " ");
}
if (postNewline) {
result.append("\n");
}
return result;
} else {
return "";
}
}
std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field);
ObjectiveCType PROTOC_EXPORT
GetObjectiveCType(FieldDescriptor::Type field_type);
inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
return GetObjectiveCType(field->type());
}
bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field);
bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field);
std::string PROTOC_EXPORT
GPBGenericValueFieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field);
std::string PROTOC_EXPORT
BuildFlagsString(const FlagType type, const std::vector<std::string>& strings);
// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
// file.
std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location,
bool prefer_single_line);
// The name the commonly used by the library when built as a framework.
// This lines up to the name used in the CocoaPod.
extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName;
// Returns the CPP symbol name to use as the gate for framework style imports
// for the given framework name to use.
std::string PROTOC_EXPORT
ProtobufFrameworkImportSymbol(const std::string& framework_name);
// Checks if the file is one of the proto's bundled with the library.
bool PROTOC_EXPORT
IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
// Checks the prefix for the given files and outputs any warnings as needed. If
// there are flat out errors, then out_error is filled in with the first error
// and the result is false.
bool PROTOC_EXPORT ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files,
const Options& validation_options, std::string* out_error);
// Same was the other ValidateObjCClassPrefixes() calls, but the options all
// come from the environment variables.
bool PROTOC_EXPORT ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files, std::string* out_error);
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
// the input into the expected output.
class PROTOC_EXPORT TextFormatDecodeData {
public:
TextFormatDecodeData();
~TextFormatDecodeData();
TextFormatDecodeData(const TextFormatDecodeData&) = delete;
TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
void AddString(int32_t key, const std::string& input_for_decode,
const std::string& desired_output);
size_t num_entries() const { return entries_.size(); }
std::string Data() const;
static std::string DecodeDataForString(const std::string& input_for_decode,
const std::string& desired_output);
private:
typedef std::pair<int32_t, std::string> DataEntry;
std::vector<DataEntry> entries_;
};
// Helper for parsing simple files.
class PROTOC_EXPORT LineConsumer {
public:
LineConsumer();
virtual ~LineConsumer();
virtual bool ConsumeLine(const absl::string_view& line, std::string* out_error) = 0;
};
bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,
LineConsumer* line_consumer,
std::string* out_error);
bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
const std::string& stream_name,
LineConsumer* line_consumer,
std::string* out_error);
// Helper class for parsing framework import mappings and generating
// import statements.
class PROTOC_EXPORT ImportWriter {
public:
ImportWriter(const std::string& generate_for_named_framework,
const std::string& named_framework_to_proto_path_mappings_path,
const std::string& runtime_import_prefix,
bool include_wkt_imports);
~ImportWriter();
void AddFile(const FileDescriptor* file, const std::string& header_extension);
void Print(io::Printer* printer) const;
static void PrintRuntimeImports(io::Printer* printer,
const std::vector<std::string>& header_to_import,
const std::string& runtime_import_prefix,
bool default_cpp_symbol = false);
private:
class ProtoFrameworkCollector : public LineConsumer {
public:
ProtoFrameworkCollector(std::map<std::string, std::string>* inout_proto_file_to_framework_name)
: map_(inout_proto_file_to_framework_name) {}
virtual bool ConsumeLine(const absl::string_view& line, std::string* out_error) override;
private:
std::map<std::string, std::string>* map_;
};
void ParseFrameworkMappings();
const std::string generate_for_named_framework_;
const std::string named_framework_to_proto_path_mappings_path_;
const std::string runtime_import_prefix_;
const bool include_wkt_imports_;
std::map<std::string, std::string> proto_file_to_framework_name_;
bool need_to_parse_mapping_file_;
std::vector<std::string> protobuf_imports_;
std::vector<std::string> other_framework_imports_;
std::vector<std::string> other_imports_;
};
// TODO(thomasvl) Move internal helpers in names.h back to here. Currently
// the dependencies are too interwoven to easily split up.
} // namespace objectivec
} // namespace compiler

@ -291,7 +291,8 @@ bool Parser::ConsumeInteger64(uint64_t max_value, uint64_t* output,
bool Parser::TryConsumeInteger64(uint64_t max_value, uint64_t* output) {
if (LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
io::Tokenizer::ParseInteger(input_->current().text, max_value, output)) {
io::Tokenizer::ParseInteger(input_->current().text, max_value,
output)) {
input_->Next();
return true;
}
@ -307,8 +308,8 @@ bool Parser::ConsumeNumber(double* output, const char* error) {
// Also accept integers.
uint64_t value = 0;
if (io::Tokenizer::ParseInteger(input_->current().text,
std::numeric_limits<uint64_t>::max(),
&value)) {
std::numeric_limits<uint64_t>::max(),
&value)) {
*output = value;
} else if (input_->current().text[0] == '0') {
// octal or hexadecimal; don't bother parsing as float
@ -429,11 +430,6 @@ Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
Init(parent, parent.source_code_info_);
}
Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
SourceCodeInfo* source_code_info) {
Init(parent, source_code_info);
}
Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
int path1,
SourceCodeInfo* source_code_info) {
@ -1263,22 +1259,13 @@ bool Parser::ParseDefaultAssignment(
field->clear_default_value();
}
LocationRecorder location(field_location,
FieldDescriptorProto::kDefaultValueFieldNumber);
DO(Consume("default"));
DO(Consume("="));
// We don't need to create separate spans in source code info for name and
// value, since there's no way to represent them distinctly in a location
// path. But we will want a separate recorder for the value, just to have more
// precise location info in error messages. So we let it create a location in
// no_op, so it doesn't add a span to the file descriptor.
SourceCodeInfo no_op;
LocationRecorder value_location(location, &no_op);
value_location.RecordLegacyLocation(
field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
LocationRecorder location(field_location,
FieldDescriptorProto::kDefaultValueFieldNumber);
location.RecordLegacyLocation(field,
DescriptorPool::ErrorCollector::DEFAULT_VALUE);
std::string* default_value = field->mutable_default_value();
if (!field->has_type()) {
@ -1356,13 +1343,12 @@ bool Parser::ParseDefaultAssignment(
}
// Parse the integer because we have to convert hex integers to decimal
// floats.
double value = 0;
double value = 0.0;
DO(ConsumeNumber(&value, "Expected number."));
// And stringify it again.
default_value->append(SimpleDtoa(value));
break;
}
case FieldDescriptorProto::TYPE_BOOL:
if (TryConsume("true")) {
default_value->assign("true");
@ -1413,23 +1399,13 @@ bool Parser::ParseJsonName(FieldDescriptorProto* field,
LocationRecorder location(field_location,
FieldDescriptorProto::kJsonNameFieldNumber);
location.RecordLegacyLocation(field,
DescriptorPool::ErrorCollector::OPTION_NAME);
// We don't need to create separate spans in source code info for name and
// value, since there's no way to represent them distinctly in a location
// path. But we will want a separate recorder for them, just to have more
// precise location info in error messages. So we let them create a location
// in no_op, so they don't add a span to the file descriptor.
SourceCodeInfo no_op;
{
LocationRecorder name_location(location, &no_op);
name_location.RecordLegacyLocation(
field, DescriptorPool::ErrorCollector::OPTION_NAME);
DO(Consume("json_name"));
}
DO(Consume("json_name"));
DO(Consume("="));
LocationRecorder value_location(location, &no_op);
LocationRecorder value_location(location);
value_location.RecordLegacyLocation(
field, DescriptorPool::ErrorCollector::OPTION_VALUE);
@ -1608,8 +1584,7 @@ bool Parser::ParseOption(Message* options,
}
break;
}
// value too large for an integer; fall through below to treat as
// floating point
// value too large for an integer; fall through below to treat as floating point
ABSL_FALLTHROUGH_INTENDED;
}
@ -1783,9 +1758,7 @@ bool Parser::ParseReservedName(std::string* name, const char* error_message) {
int col = input_->current().column;
DO(ConsumeString(name, error_message));
if (!io::Tokenizer::IsIdentifier(*name)) {
AddWarning(line, col,
absl::StrFormat(
"Reserved name \"%s\" is not a valid identifier.", *name));
AddWarning(line, col, absl::StrFormat("Reserved name \"%s\" is not a valid identifier.", *name));
}
return true;
}
@ -1883,7 +1856,8 @@ bool Parser::ParseReservedNumbers(EnumDescriptorProto* proto,
do {
LocationRecorder location(parent_location, proto->reserved_range_size());
EnumDescriptorProto::EnumReservedRange* range = proto->add_reserved_range();
EnumDescriptorProto::EnumReservedRange* range =
proto->add_reserved_range();
int start, end;
io::Tokenizer::Token start_token;
{

@ -245,10 +245,6 @@ class PROTOBUF_EXPORT Parser {
LocationRecorder(const LocationRecorder& parent, int path1, int path2);
// Creates a recorder that generates locations into given source code info.
LocationRecorder(const LocationRecorder& parent,
SourceCodeInfo* source_code_info);
// Creates a recorder that generates locations into given source code info
// and calls AddPath() one time.
LocationRecorder(const LocationRecorder& parent, int path1,
SourceCodeInfo* source_code_info);

@ -1737,11 +1737,13 @@ TEST_F(ParseErrorTest, EnumReservedMissingQuotes) {
TEST_F(ParseErrorTest, EnumReservedInvalidIdentifier) {
ExpectHasWarnings(
"enum TestEnum {\n"
" FOO = 1;\n"
" reserved \"foo bar\";\n"
"}\n",
"2:11: Reserved name \"foo bar\" is not a valid identifier.\n");
R"pb(
enum TestEnum {
FOO = 1;
reserved "foo bar";
}
)pb",
"3:17: Reserved name \"foo bar\" is not a valid identifier.\n");
}
// -------------------------------------------------------------------
@ -1773,10 +1775,12 @@ TEST_F(ParseErrorTest, ReservedMissingQuotes) {
TEST_F(ParseErrorTest, ReservedInvalidIdentifier) {
ExpectHasWarnings(
"enum TestEnum {\n"
" reserved \"foo bar\";\n"
"}\n",
"1:11: Reserved name \"foo bar\" is not a valid identifier.\n");
R"pb(
message Foo {
reserved "foo bar";
}
)pb",
"2:17: Reserved name \"foo bar\" is not a valid identifier.\n");
}
TEST_F(ParseErrorTest, ReservedNegativeNumber) {
@ -2070,117 +2074,8 @@ TEST_F(ParserValidationErrorTest, Proto3JsonConflictError) {
" uint32 foo = 1;\n"
" uint32 Foo = 2;\n"
"}\n",
"3:9: The default JSON name of field \"Foo\" (\"Foo\") conflicts "
"with the default JSON name of field \"foo\" (\"foo\"). "
"This is not allowed in proto3.\n");
}
TEST_F(ParserValidationErrorTest, Proto2JsonConflictError) {
// conflicts with default JSON names are not errors in proto2
ExpectParsesTo(
R"pb(
syntax = "proto2"
;
message TestMessage {
optional uint32 foo = 1;
optional uint32 Foo = 2;
}
)pb",
R"pb(
syntax: 'proto2'
message_type {
name: 'TestMessage'
field {
label: LABEL_OPTIONAL
type: TYPE_UINT32
name: 'foo'
number: 1
}
field {
label: LABEL_OPTIONAL
type: TYPE_UINT32
name: 'Foo'
number: 2
}
}
)pb");
}
TEST_F(ParserValidationErrorTest, Proto2CustomJsonConflictWithDefaultError) {
// conflicts with default JSON names are not errors in proto2
ExpectParsesTo(
R"pb(
syntax = 'proto2'
;
message TestMessage {
optional uint32 foo = 1 [json_name='bar'];
optional uint32 bar = 2;
}
)pb",
R"pb(
syntax: 'proto2'
message_type {
name: 'TestMessage'
field {
label: LABEL_OPTIONAL
type: TYPE_UINT32
name: 'foo'
number: 1
json_name: 'bar'
}
field {
label: LABEL_OPTIONAL
type: TYPE_UINT32
name: 'bar'
number: 2
}
}
)pb");
}
// TODO(b/248626372) Re-enable these in google3.
TEST_F(ParserValidationErrorTest, Proto3CustomJsonConflictWithDefaultError) {
ExpectHasValidationErrors(
R"pb(
syntax = 'proto3'
;
message TestMessage {
uint32 foo = 1 [json_name='bar'];
uint32 bar = 2;
}
)pb",
"5:15: The default JSON name of field \"bar\" (\"bar\") conflicts "
"with the custom JSON name of field \"foo\". "
"This is not allowed in proto3.\n");
}
TEST_F(ParserValidationErrorTest, Proto3CustomJsonConflictError) {
ExpectHasValidationErrors(
R"pb(
syntax = 'proto3'
;
message TestMessage {
uint32 foo = 1 [json_name='baz'];
uint32 bar = 2 [json_name='baz'];
}
)pb",
"5:15: The custom JSON name of field \"bar\" (\"baz\") conflicts "
"with the custom JSON name of field \"foo\".\n");
}
TEST_F(ParserValidationErrorTest, Proto2CustomJsonConflictError) {
ExpectHasValidationErrors(
R"pb(
syntax = 'proto2'
;
message TestMessage {
optional uint32 foo = 1 [json_name='baz'];
optional uint32 bar = 2 [json_name='baz'];
}
)pb",
// fails in proto2 also: can't explicitly configure bad custom JSON names
"5:24: The custom JSON name of field \"bar\" (\"baz\") conflicts "
"with the custom JSON name of field \"foo\".\n");
"3:9: The JSON camel-case name of field \"Foo\" conflicts with field "
"\"foo\". This is not allowed in proto3.\n");
}
TEST_F(ParserValidationErrorTest, EnumNameError) {
@ -3617,19 +3512,18 @@ TEST_F(SourceInfoTest, FieldOptions) {
EXPECT_TRUE(
Parse("message Foo {"
" optional int32 bar = 1 "
"$a$[$b$default=123$c$, $d$opt1=123$e$, "
"$f$opt2='hi'$g$, $h$json_name='barBar'$i$]$j$;"
"$a$[default=$b$123$c$,$d$opt1=123$e$,"
"$f$opt2='hi'$g$]$h$;"
"}\n"));
const FieldDescriptorProto& field = file_.message_type(0).field(0);
const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
EXPECT_TRUE(HasSpan('a', 'j', field.options()));
EXPECT_TRUE(HasSpan('a', 'h', field.options()));
EXPECT_TRUE(HasSpan('b', 'c', field, "default_value"));
EXPECT_TRUE(HasSpan('d', 'e', option1));
EXPECT_TRUE(HasSpan('f', 'g', option2));
EXPECT_TRUE(HasSpan('h', 'i', field, "json_name"));
// Ignore these.
EXPECT_TRUE(HasSpan(file_));

@ -6,6 +6,20 @@ load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("//build_defs:cpp_opts.bzl", "COPTS")
cc_library(
name = "names",
hdrs = ["names.h"],
srcs = ["names.cc"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/php",
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/strings",
],
)
cc_library(
name = "php",
srcs = ["php_generator.cc"],
@ -17,6 +31,7 @@ cc_library(
"//src/google/protobuf/compiler:__pkg__",
],
deps = [
":names",
"//src/google/protobuf:protobuf_nowkt",
"//src/google/protobuf/compiler:code_generator",
"@com_google_absl//absl/strings",

@ -0,0 +1,144 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "google/protobuf/compiler/php/names.h"
#include <string>
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/plugin.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
const char* const kReservedNames[] = {
"abstract", "and", "array", "as", "break",
"callable", "case", "catch", "class", "clone",
"const", "continue", "declare", "default", "die",
"do", "echo", "else", "elseif", "empty",
"enddeclare", "endfor", "endforeach", "endif", "endswitch",
"endwhile", "eval", "exit", "extends", "final",
"finally", "fn", "for", "foreach", "function",
"global", "goto", "if", "implements", "include",
"include_once", "instanceof", "insteadof", "interface", "isset",
"list", "match", "namespace", "new", "or",
"parent", "print", "private", "protected", "public",
"readonly", "require", "require_once", "return", "self",
"static", "switch", "throw", "trait", "try",
"unset", "use", "var", "while", "xor",
"yield", "int", "float", "bool", "string",
"true", "false", "null", "void", "iterable"};
const int kReservedNamesSize = 80;
namespace google {
namespace protobuf {
namespace compiler {
namespace php {
bool IsReservedName(absl::string_view name) {
std::string lower(name);
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
for (int i = 0; i < kReservedNamesSize; i++) {
if (lower == kReservedNames[i]) {
return true;
}
}
return false;
}
std::string ReservedNamePrefix(const std::string& classname,
const FileDescriptor* file) {
if (IsReservedName(classname)) {
if (file->package() == "google.protobuf") {
return "GPB";
} else {
return "PB";
}
}
return "";
}
namespace {
template <typename DescriptorType>
std::string ClassNamePrefixImpl(const std::string& classname,
const DescriptorType* desc) {
const std::string& prefix = (desc->file()->options()).php_class_prefix();
if (!prefix.empty()) {
return prefix;
}
return ReservedNamePrefix(classname, desc->file());
}
template <typename DescriptorType>
std::string GeneratedClassNameImpl(const DescriptorType* desc) {
std::string classname = ClassNamePrefixImpl(desc->name(), desc) + desc->name();
const Descriptor* containing = desc->containing_type();
while (containing != NULL) {
classname = ClassNamePrefixImpl(containing->name(), desc) + containing->name()
+ '\\' + classname;
containing = containing->containing_type();
}
return classname;
}
std::string GeneratedClassNameImpl(const ServiceDescriptor* desc) {
std::string classname = desc->name();
return ClassNamePrefixImpl(classname, desc) + classname;
}
} // namespace
std::string ClassNamePrefix(const std::string& classname,
const Descriptor* desc) {
return ClassNamePrefixImpl(classname, desc);
}
std::string ClassNamePrefix(const std::string& classname,
const EnumDescriptor* desc) {
return ClassNamePrefixImpl(classname, desc);
}
std::string GeneratedClassName(const Descriptor* desc) {
return GeneratedClassNameImpl(desc);
}
std::string GeneratedClassName(const EnumDescriptor* desc) {
return GeneratedClassNameImpl(desc);
}
std::string GeneratedClassName(const ServiceDescriptor* desc) {
return GeneratedClassNameImpl(desc);
}
} // namespace php
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_PHP_NAMES_H__
#define GOOGLE_PROTOBUF_COMPILER_PHP_NAMES_H__
#include "google/protobuf/descriptor.h"
#include <string>
#include "absl/strings/string_view.h"
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace compiler {
namespace php {
// Whether or not a name is reserved.
PROTOC_EXPORT bool IsReservedName(absl::string_view name);
// A prefix to stick in front of reserved names to avoid clashes.
PROTOC_EXPORT std::string ReservedNamePrefix(const std::string& classname,
const FileDescriptor* file);
// A prefix to stick in front of all class names.
PROTOC_EXPORT std::string ClassNamePrefix(const std::string& classname,
const Descriptor* desc);
PROTOC_EXPORT std::string ClassNamePrefix(const std::string& classname,
const EnumDescriptor* desc);
// To skip reserved keywords in php, some generated classname are prefixed.
// Other code generators may need following API to figure out the actual
// classname.
PROTOC_EXPORT std::string GeneratedClassName(const Descriptor* desc);
PROTOC_EXPORT std::string GeneratedClassName(const EnumDescriptor* desc);
PROTOC_EXPORT std::string GeneratedClassName(const ServiceDescriptor* desc);
} // namespace php
} // namespace compiler
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_PHP_NAMES_H__

@ -50,29 +50,11 @@ const std::string kDescriptorMetadataFile =
"GPBMetadata/Google/Protobuf/Internal/Descriptor.php";
const std::string kDescriptorDirName = "Google/Protobuf/Internal";
const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal";
const char* const kReservedNames[] = {
"abstract", "and", "array", "as", "break",
"callable", "case", "catch", "class", "clone",
"const", "continue", "declare", "default", "die",
"do", "echo", "else", "elseif", "empty",
"enddeclare", "endfor", "endforeach", "endif", "endswitch",
"endwhile", "eval", "exit", "extends", "final",
"finally", "fn", "for", "foreach", "function",
"global", "goto", "if", "implements", "include",
"include_once", "instanceof", "insteadof", "interface", "isset",
"list", "match", "namespace", "new", "or",
"parent", "print", "private", "protected", "public",
"readonly", "require", "require_once", "return", "self",
"static", "switch", "throw", "trait", "try",
"unset", "use", "var", "while", "xor",
"yield", "int", "float", "bool", "string",
"true", "false", "null", "void", "iterable"};
const char* const kValidConstantNames[] = {
"int", "float", "bool", "string", "true",
"false", "null", "void", "iterable", "parent",
"self", "readonly"
};
const int kReservedNamesSize = 80;
const int kValidConstantNamesSize = 12;
const int kFieldSetter = 1;
const int kFieldGetter = 2;
@ -124,31 +106,6 @@ void GenerateServiceDocComment(io::Printer* printer,
void GenerateServiceMethodDocComment(io::Printer* printer,
const MethodDescriptor* method);
std::string ReservedNamePrefix(const std::string& classname,
const FileDescriptor* file) {
bool is_reserved = false;
std::string lower = classname;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
for (int i = 0; i < kReservedNamesSize; i++) {
if (lower == kReservedNames[i]) {
is_reserved = true;
break;
}
}
if (is_reserved) {
if (file->package() == "google.protobuf") {
return "GPB";
} else {
return "PB";
}
}
return "";
}
template <typename DescriptorType>
std::string DescriptorFullName(const DescriptorType* desc, bool is_internal) {
if (is_internal) {
@ -159,34 +116,6 @@ std::string DescriptorFullName(const DescriptorType* desc, bool is_internal) {
}
}
template <typename DescriptorType>
std::string ClassNamePrefix(const std::string& classname,
const DescriptorType* desc) {
const std::string& prefix = (desc->file()->options()).php_class_prefix();
if (!prefix.empty()) {
return prefix;
}
return ReservedNamePrefix(classname, desc->file());
}
template <typename DescriptorType>
std::string GeneratedClassNameImpl(const DescriptorType* desc) {
std::string classname = ClassNamePrefix(desc->name(), desc) + desc->name();
const Descriptor* containing = desc->containing_type();
while (containing != NULL) {
classname = ClassNamePrefix(containing->name(), desc) + containing->name()
+ '\\' + classname;
containing = containing->containing_type();
}
return classname;
}
std::string GeneratedClassNameImpl(const ServiceDescriptor* desc) {
std::string classname = desc->name();
return ClassNamePrefix(classname, desc) + classname;
}
template <typename DescriptorType>
std::string LegacyGeneratedClassName(const DescriptorType* desc) {
std::string classname = desc->name();
@ -198,31 +127,13 @@ std::string LegacyGeneratedClassName(const DescriptorType* desc) {
return ClassNamePrefix(classname, desc) + classname;
}
std::string ClassNamePrefix(const std::string& classname) {
std::string lower = classname;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
for (int i = 0; i < kReservedNamesSize; i++) {
if (lower == kReservedNames[i]) {
return "PB";
}
}
return "";
}
std::string ConstantNamePrefix(const std::string& classname) {
bool is_reserved = false;
std::string lower = classname;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
for (int i = 0; i < kReservedNamesSize; i++) {
if (lower == kReservedNames[i]) {
is_reserved = true;
break;
}
}
is_reserved = IsReservedName(lower);
for (int i = 0; i < kValidConstantNamesSize; i++) {
if (lower == kValidConstantNames[i]) {
@ -257,7 +168,7 @@ std::string RootPhpNamespace(const DescriptorType* desc,
template <typename DescriptorType>
std::string FullClassName(const DescriptorType* desc, const Options& options) {
std::string classname = GeneratedClassNameImpl(desc);
std::string classname = GeneratedClassName(desc);
std::string php_namespace = RootPhpNamespace(desc, options);
if (!php_namespace.empty()) {
return php_namespace + "\\" + classname;
@ -283,6 +194,11 @@ std::string LegacyFullClassName(const DescriptorType* desc,
return classname;
}
std::string PhpNamePrefix(const std::string& classname) {
if (IsReservedName(classname)) return "PB";
return "";
}
std::string PhpName(const std::string& full_name, const Options& options) {
if (options.is_descriptor) {
return kDescriptorPackageName;
@ -296,7 +212,7 @@ std::string PhpName(const std::string& full_name, const Options& options) {
segment += full_name[i] + ('A' - 'a');
cap_next_letter = false;
} else if (full_name[i] == '.') {
result += ClassNamePrefix(segment) + segment + '\\';
result += PhpNamePrefix(segment) + segment + '\\';
segment = "";
cap_next_letter = true;
} else {
@ -304,7 +220,7 @@ std::string PhpName(const std::string& full_name, const Options& options) {
cap_next_letter = false;
}
}
result += ClassNamePrefix(segment) + segment;
result += PhpNamePrefix(segment) + segment;
return result;
}
@ -1312,7 +1228,7 @@ void LegacyGenerateClassFile(const FileDescriptor* file,
Outdent(&printer);
printer.Print("}\n");
printer.Print("class_exists(^new^::class);\n",
"new", GeneratedClassNameImpl(desc));
"new", GeneratedClassName(desc));
printer.Print("@trigger_error('^old^ is deprecated and will be removed in "
"the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n",
"old", LegacyFullClassName(desc, options),
@ -2342,18 +2258,6 @@ void GenerateCWellKnownTypes(const std::vector<const FileDescriptor*>& files,
} // namespace
std::string GeneratedClassName(const Descriptor* desc) {
return GeneratedClassNameImpl(desc);
}
std::string GeneratedClassName(const EnumDescriptor* desc) {
return GeneratedClassNameImpl(desc);
}
std::string GeneratedClassName(const ServiceDescriptor* desc) {
return GeneratedClassNameImpl(desc);
}
bool Generator::Generate(const FileDescriptor* file,
const std::string& parameter,
GeneratorContext* generator_context,

@ -32,6 +32,7 @@
#define GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/php/names.h"
#include "google/protobuf/descriptor.h"
#include <string>
@ -70,13 +71,6 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
std::string* error) const;
};
// To skip reserved keywords in php, some generated classname are prefixed.
// Other code generators may need following API to figure out the actual
// classname.
PROTOC_EXPORT std::string GeneratedClassName(const Descriptor* desc);
PROTOC_EXPORT std::string GeneratedClassName(const EnumDescriptor* desc);
PROTOC_EXPORT std::string GeneratedClassName(const ServiceDescriptor* desc);
inline bool IsWrapperType(const FieldDescriptor* descriptor) {
return descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto";

@ -23,6 +23,7 @@ cc_library(
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",
"@com_github_grpc_grpc//tools/distrib/python/grpcio_tools:__subpackages__",
],
deps = [
"//src/google/protobuf:protobuf_nowkt",

@ -3855,6 +3855,8 @@ class DescriptorBuilder {
internal::FlatAllocator& alloc);
void BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent,
OneofDescriptor* result, internal::FlatAllocator& alloc);
void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
const EnumDescriptor* result);
void BuildEnum(const EnumDescriptorProto& proto, const Descriptor* parent,
EnumDescriptor* result, internal::FlatAllocator& alloc);
void BuildEnumValue(const EnumValueDescriptorProto& proto,
@ -3866,15 +3868,6 @@ class DescriptorBuilder {
const ServiceDescriptor* parent, MethodDescriptor* result,
internal::FlatAllocator& alloc);
void CheckFieldJsonNameUniqueness(const DescriptorProto& proto,
const Descriptor* result);
void CheckFieldJsonNameUniqueness(const std::string& message_name,
const DescriptorProto& message,
FileDescriptor::Syntax syntax,
bool use_custom_names);
void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
const EnumDescriptor* result);
void LogUnusedDependency(const FileDescriptorProto& proto,
const FileDescriptor* result);
@ -5430,11 +5423,7 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
}
}
// TODO(b/248626372) Make this consistent with OSS behavior.
CheckFieldJsonNameUniqueness(proto, result);
// Check that fields aren't using reserved names or numbers and that they
// aren't using extension numbers.
for (int i = 0; i < result->field_count(); i++) {
const FieldDescriptor* field = result->field(i);
for (int j = 0; j < result->extension_range_count(); j++) {
@ -5499,83 +5488,6 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
}
}
void DescriptorBuilder::CheckFieldJsonNameUniqueness(
const DescriptorProto& proto, const Descriptor* result) {
FileDescriptor::Syntax syntax = result->file()->syntax();
std::string message_name = result->full_name();
// two passes: one looking only at default JSON names, and one that considers
// custom JSON names
CheckFieldJsonNameUniqueness(message_name, proto, syntax, false);
CheckFieldJsonNameUniqueness(message_name, proto, syntax, true);
}
namespace {
// Helpers for function below
struct JsonNameDetails {
const FieldDescriptorProto* field;
std::string orig_name;
bool is_custom;
};
JsonNameDetails GetJsonNameDetails(const FieldDescriptorProto* field,
bool use_custom) {
if (use_custom && field->has_json_name()) {
return {field, field->json_name(), true};
}
return {field, ToJsonName(field->name()), false};
}
} // namespace
void DescriptorBuilder::CheckFieldJsonNameUniqueness(
const std::string& message_name, const DescriptorProto& message,
FileDescriptor::Syntax syntax, bool use_custom_names) {
absl::flat_hash_map<std::string, JsonNameDetails> name_to_field;
for (const FieldDescriptorProto& field : message.field()) {
JsonNameDetails details = GetJsonNameDetails(&field, use_custom_names);
std::string lowercase_name = absl::AsciiStrToLower(details.orig_name);
auto existing = name_to_field.find(lowercase_name);
if (existing == name_to_field.end()) {
name_to_field[lowercase_name] = details;
continue;
}
JsonNameDetails& match = existing->second;
if (use_custom_names && !details.is_custom && !match.is_custom) {
// if this pass is considering custom JSON names, but neither of the
// names involved in the conflict are custom, don't bother with a
// message. That will have been reported from other pass (non-custom
// JSON names).
continue;
}
absl::string_view this_type = details.is_custom ? "custom" : "default";
absl::string_view existing_type = match.is_custom ? "custom" : "default";
// If the matched name differs (which it can only differ in case), include
// it in the error message, for maximum clarity to user.
std::string name_suffix;
if (details.orig_name != match.orig_name) {
name_suffix = absl::StrCat(" (\"", match.orig_name, "\")");
}
std::string error_message = absl::StrFormat(
"The %s JSON name of field \"%s\" (\"%s\") conflicts "
"with the %s JSON name of field \"%s\"%s.",
this_type, field.name(), details.orig_name, existing_type,
match.field->name(), name_suffix);
bool involves_default = !details.is_custom || !match.is_custom;
if (syntax == FileDescriptor::SYNTAX_PROTO2 && involves_default) {
AddWarning(message_name, field, DescriptorPool::ErrorCollector::NAME,
error_message);
} else {
if (involves_default) {
absl::StrAppend(&error_message, " This is not allowed in proto3.");
}
AddError(message_name, field, DescriptorPool::ErrorCollector::NAME,
error_message);
}
}
}
void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
Descriptor* parent,
FieldDescriptor* result,
@ -5979,12 +5891,13 @@ void DescriptorBuilder::CheckEnumValueUniqueness(
// NAME_TYPE_LAST_NAME = 2,
// }
PrefixRemover remover(result->name());
absl::flat_hash_map<std::string, const EnumValueDescriptor*> values;
std::map<std::string, const EnumValueDescriptor*> values;
for (int i = 0; i < result->value_count(); i++) {
const EnumValueDescriptor* value = result->value(i);
std::string stripped =
EnumValueToPascalCase(remover.MaybeRemove(value->name()));
auto insert_result = values.insert(std::make_pair(stripped, value));
std::pair<std::map<std::string, const EnumValueDescriptor*>::iterator, bool>
insert_result = values.insert(std::make_pair(stripped, value));
bool inserted = insert_result.second;
// We don't throw the error if the two conflicting symbols are identical, or
@ -5995,18 +5908,19 @@ void DescriptorBuilder::CheckEnumValueUniqueness(
// stripping should de-dup the labels in this case).
if (!inserted && insert_result.first->second->name() != value->name() &&
insert_result.first->second->number() != value->number()) {
std::string error_message = absl::StrFormat(
"Enum name %s has the same name as %s if you ignore case and strip "
"out the enum name prefix (if any). (If you are using allow_alias, "
"please assign the same numeric value to both enums.)",
value->name(), values[stripped]->name());
std::string error_message =
"Enum name " + value->name() + " has the same name as " +
values[stripped]->name() +
" if you ignore case and strip out the enum name prefix (if any). "
"This is error-prone and can lead to undefined behavior. "
"Please avoid doing this. If you are using allow_alias, please "
"assign the same numeric value to both enums.";
// There are proto2 enums out there with conflicting names, so to preserve
// compatibility we issue only a warning for proto2.
if (result->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) {
AddWarning(value->full_name(), proto.value(i),
DescriptorPool::ErrorCollector::NAME, error_message);
} else {
absl::StrAppend(&error_message, " This is not allowed in proto3.");
AddError(value->full_name(), proto.value(i),
DescriptorPool::ErrorCollector::NAME, error_message);
}
@ -6873,6 +6787,19 @@ void DescriptorBuilder::ValidateProto3(FileDescriptor* file,
}
}
static std::string ToLowercaseWithoutUnderscores(const std::string& name) {
std::string result;
for (char character : name) {
if (character != '_') {
if (character >= 'A' && character <= 'Z') {
result.push_back(character - 'A' + 'a');
} else {
result.push_back(character);
}
}
}
return result;
}
void DescriptorBuilder::ValidateProto3Message(Descriptor* message,
const DescriptorProto& proto) {
@ -6899,6 +6826,24 @@ void DescriptorBuilder::ValidateProto3Message(Descriptor* message,
"MessageSet is not supported in proto3.");
}
// In proto3, we reject field names if they conflict in camelCase.
// Note that we currently enforce a stricter rule: Field names must be
// unique after being converted to lowercase with underscores removed.
std::map<std::string, const FieldDescriptor*> name_to_field;
for (int i = 0; i < message->field_count(); ++i) {
std::string lowercase_name =
ToLowercaseWithoutUnderscores(message->field(i)->name());
if (name_to_field.find(lowercase_name) != name_to_field.end()) {
AddError(message->full_name(), proto.field(i),
DescriptorPool::ErrorCollector::NAME,
"The JSON camel-case name of field \"" +
message->field(i)->name() + "\" conflicts with field \"" +
name_to_field[lowercase_name]->name() + "\". This is not " +
"allowed in proto3.");
} else {
name_to_field[lowercase_name] = message->field(i);
}
}
}
void DescriptorBuilder::ValidateProto3Field(FieldDescriptor* field,
@ -7741,24 +7686,23 @@ bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet(
namespace {
// Helpers for method below
template <typename T>
std::string ValueOutOfRange(absl::string_view type_name,
absl::string_view option_name) {
return absl::StrFormat("Value out of range, %d to %d, for %s option \"%s\".",
std::numeric_limits<T>::min(),
std::numeric_limits<T>::max(), type_name, option_name);
template <typename T> std::string ValueOutOfRange(
absl::string_view type_name, absl::string_view option_name) {
return absl::StrFormat(
"Value out of range, %d to %d, for %s option \"%s\".", \
std::numeric_limits<T>::min(), std::numeric_limits<T>::max(),
type_name, option_name);
}
template <typename T>
std::string ValueMustBeInt(absl::string_view type_name,
absl::string_view option_name) {
template <typename T> std::string ValueMustBeInt(
absl::string_view type_name, absl::string_view option_name) {
return absl::StrFormat(
"Value must be integer, from %d to %d, for %s option \"%s\".",
std::numeric_limits<T>::min(), std::numeric_limits<T>::max(), type_name,
option_name);
"Value must be integer, from %d to %d, for %s option \"%s\".", \
std::numeric_limits<T>::min(), std::numeric_limits<T>::max(),
type_name, option_name);
}
} // namespace
} // namespace
bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) {
@ -7768,8 +7712,7 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
if (uninterpreted_option_->has_positive_int_value()) {
if (uninterpreted_option_->positive_int_value() >
static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) {
return AddValueError(
ValueOutOfRange<int32_t>("int32", option_field->full_name()));
return AddValueError(ValueOutOfRange<int32_t>("int32", option_field->full_name()));
} else {
SetInt32(option_field->number(),
uninterpreted_option_->positive_int_value(),
@ -7778,16 +7721,14 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
} else if (uninterpreted_option_->has_negative_int_value()) {
if (uninterpreted_option_->negative_int_value() <
static_cast<int64_t>(std::numeric_limits<int32_t>::min())) {
return AddValueError(
ValueOutOfRange<int32_t>("int32", option_field->full_name()));
return AddValueError(ValueOutOfRange<int32_t>("int32", option_field->full_name()));
} else {
SetInt32(option_field->number(),
uninterpreted_option_->negative_int_value(),
option_field->type(), unknown_fields);
}
} else {
return AddValueError(
ValueMustBeInt<int32_t>("int32", option_field->full_name()));
return AddValueError(ValueMustBeInt<int32_t>("int32", option_field->full_name()));
}
break;
@ -7795,8 +7736,7 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
if (uninterpreted_option_->has_positive_int_value()) {
if (uninterpreted_option_->positive_int_value() >
static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
return AddValueError(
ValueOutOfRange<int64_t>("int64", option_field->full_name()));
return AddValueError(ValueOutOfRange<int64_t>("int64", option_field->full_name()));
} else {
SetInt64(option_field->number(),
uninterpreted_option_->positive_int_value(),
@ -7807,8 +7747,7 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
uninterpreted_option_->negative_int_value(),
option_field->type(), unknown_fields);
} else {
return AddValueError(
ValueMustBeInt<int64_t>("int64", option_field->full_name()));
return AddValueError(ValueMustBeInt<int64_t>("int64", option_field->full_name()));
}
break;
@ -7816,16 +7755,14 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
if (uninterpreted_option_->has_positive_int_value()) {
if (uninterpreted_option_->positive_int_value() >
std::numeric_limits<uint32_t>::max()) {
return AddValueError(
ValueOutOfRange<uint32_t>("uint32", option_field->full_name()));
return AddValueError(ValueOutOfRange<uint32_t>("uint32", option_field->full_name()));
} else {
SetUInt32(option_field->number(),
uninterpreted_option_->positive_int_value(),
option_field->type(), unknown_fields);
}
} else {
return AddValueError(
ValueMustBeInt<uint32_t>("uint32", option_field->full_name()));
return AddValueError(ValueMustBeInt<uint32_t>("uint32", option_field->full_name()));
}
break;
@ -7835,8 +7772,7 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
uninterpreted_option_->positive_int_value(),
option_field->type(), unknown_fields);
} else {
return AddValueError(
ValueMustBeInt<uint64_t>("uint64", option_field->full_name()));
return AddValueError(ValueMustBeInt<uint64_t>("uint64", option_field->full_name()));
}
break;

@ -5624,8 +5624,7 @@ TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
" positive_int_value: 0x80000000 } "
"}",
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, -2147483648 to "
"2147483647, "
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, -2147483648 to 2147483647, "
"for int32 option \"foo\".\n");
}
@ -5642,8 +5641,7 @@ TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
" negative_int_value: -0x80000001 } "
"}",
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, -2147483648 to "
"2147483647, "
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, -2147483648 to 2147483647, "
"for int32 option \"foo\".\n");
}
@ -5659,8 +5657,7 @@ TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
" is_extension: true } "
" string_value: \"5\" } }",
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from "
"-2147483648 to 2147483647, "
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from -2147483648 to 2147483647, "
"for int32 option \"foo\".\n");
}
@ -5678,8 +5675,7 @@ TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
"} "
"}",
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, "
"-9223372036854775808 to 9223372036854775807, "
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, -9223372036854775808 to 9223372036854775807, "
"for int64 option \"foo\".\n");
}
@ -5695,8 +5691,7 @@ TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
" is_extension: true } "
" identifier_value: \"5\" } }",
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from "
"-9223372036854775808 to 9223372036854775807, "
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from -9223372036854775808 to 9223372036854775807, "
"for int64 option \"foo\".\n");
}
@ -5712,8 +5707,7 @@ TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
" is_extension: true } "
" positive_int_value: 0x100000000 } }",
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, 0 to "
"4294967295, "
"foo.proto: foo.proto: OPTION_VALUE: Value out of range, 0 to 4294967295, "
"for uint32 option \"foo\".\n");
}
@ -5729,8 +5723,7 @@ TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
" is_extension: true } "
" double_value: -5.6 } }",
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from 0 to "
"4294967295, "
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from 0 to 4294967295, "
"for uint32 option \"foo\".\n");
}
@ -5746,8 +5739,7 @@ TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
" is_extension: true } "
" negative_int_value: -5 } }",
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from 0 to "
"18446744073709551615, "
"foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from 0 to 18446744073709551615, "
"for uint64 option \"foo\".\n");
}
@ -6486,10 +6478,9 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWithDifferentCasing) {
"}",
"foo.proto: bar: NAME: Enum name bar has the same name as BAR "
"if you ignore case and strip out the enum name prefix (if any). "
"(If you are using allow_alias, please assign the same numeric "
"value to both enums.)"
" This is not allowed in proto3.\n"
);
"This is error-prone and can lead to undefined behavior. "
"Please avoid doing this. If you are using allow_alias, please assign "
"the same numeric value to both enums.\n");
// Not an error because both enums are mapped to the same value.
BuildFile(
@ -6505,20 +6496,6 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWithDifferentCasing) {
}
TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
BuildFileWithErrors(
"syntax: 'proto3'"
"name: 'foo.proto' "
"enum_type {"
" name: 'FooEnum' "
" value { name: 'BAR' number: 0 }"
" value { name: 'bar' number: 1 }"
"}",
"foo.proto: bar: NAME: Enum name bar has the same name as BAR "
"if you ignore case and strip out the enum name prefix (if any). "
"(If you are using allow_alias, please assign the same numeric "
"value to both enums.)"
" This is not allowed in proto3.\n"
);
BuildFileWithErrors(
"syntax: 'proto3'"
"name: 'foo.proto' "
@ -6529,10 +6506,9 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
"}",
"foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOO_ENUM_BAZ "
"if you ignore case and strip out the enum name prefix (if any). "
"(If you are using allow_alias, please assign the same numeric value "
"to both enums.)"
" This is not allowed in proto3.\n"
);
"This is error-prone and can lead to undefined behavior. "
"Please avoid doing this. If you are using allow_alias, please assign "
"the same numeric value to both enums.\n");
BuildFileWithErrors(
"syntax: 'proto3'"
@ -6544,10 +6520,9 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
"}",
"foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOOENUM_BAZ "
"if you ignore case and strip out the enum name prefix (if any). "
"(If you are using allow_alias, please assign the same numeric value "
"to both enums.)"
" This is not allowed in proto3.\n"
);
"This is error-prone and can lead to undefined behavior. "
"Please avoid doing this. If you are using allow_alias, please assign "
"the same numeric value to both enums.\n");
BuildFileWithErrors(
"syntax: 'proto3'"
@ -6559,10 +6534,9 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
"}",
"foo.proto: BAR__BAZ: NAME: Enum name BAR__BAZ has the same name as "
"FOO_ENUM_BAR_BAZ if you ignore case and strip out the enum name prefix "
"(if any). (If you are using allow_alias, please assign the same numeric "
"value to both enums.)"
" This is not allowed in proto3.\n"
);
"(if any). This is error-prone and can lead to undefined behavior. "
"Please avoid doing this. If you are using allow_alias, please assign "
"the same numeric value to both enums.\n");
BuildFileWithErrors(
"syntax: 'proto3'"
@ -6574,10 +6548,9 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
"}",
"foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as "
"FOO_ENUM__BAR_BAZ if you ignore case and strip out the enum name prefix "
"(if any). (If you are using allow_alias, please assign the same numeric "
"value to both enums.)"
" This is not allowed in proto3.\n"
);
"(if any). This is error-prone and can lead to undefined behavior. "
"Please avoid doing this. If you are using allow_alias, please assign "
"the same numeric value to both enums.\n");
// This isn't an error because the underscore will cause the PascalCase to
// differ by case (BarBaz vs. Barbaz).
@ -6913,7 +6886,6 @@ TEST_F(ValidationErrorTest, ValidateProto3Extension) {
// Test that field names that may conflict in JSON is not allowed by protoc.
TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
// TODO(b/248626372) Re-enable this once they're errors in google3.
// The comparison is case-insensitive.
BuildFileWithErrors(
"name: 'foo.proto' "
@ -6923,11 +6895,8 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
" field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
" field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
"}",
"foo.proto: Foo: NAME: The default JSON name of field \"Name\" "
"(\"Name\") "
"conflicts with the default JSON name of field \"name\" (\"name\"). This "
"is "
"not allowed in proto3.\n");
"foo.proto: Foo: NAME: The JSON camel-case name of field \"Name\" "
"conflicts with field \"name\". This is not allowed in proto3.\n");
// Underscores are ignored.
BuildFileWithErrors(
"name: 'foo.proto' "
@ -6937,11 +6906,8 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
" field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
" field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
"}",
"foo.proto: Foo: NAME: The default JSON name of field \"_a__b_\" "
"(\"AB\") "
"conflicts with the default JSON name of field \"ab\" (\"ab\"). This is "
"not "
"allowed in proto3.\n");
"foo.proto: Foo: NAME: The JSON camel-case name of field \"_a__b_\" "
"conflicts with field \"ab\". This is not allowed in proto3.\n");
}

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

Loading…
Cancel
Save