diff options
-rw-r--r-- | conformance/failure_list_csharp.txt | 4 | ||||
-rw-r--r-- | csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs | 12 | ||||
-rw-r--r-- | csharp/src/Google.Protobuf/JsonFormatter.cs | 84 | ||||
-rw-r--r-- | csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs | 2 | ||||
-rw-r--r-- | csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs | 10 | ||||
-rw-r--r-- | docs/third_party.md | 1 | ||||
-rw-r--r-- | objectivec/GPBMessage.h | 11 | ||||
-rw-r--r-- | src/google/protobuf/compiler/mock_code_generator.cc | 8 | ||||
-rw-r--r-- | src/google/protobuf/stubs/atomicops_internals_generic_gcc.h | 10 |
9 files changed, 43 insertions, 99 deletions
diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt index dfafbecc..84f46fab 100644 --- a/conformance/failure_list_csharp.txt +++ b/conformance/failure_list_csharp.txt @@ -1,6 +1,2 @@ Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput Required.JsonInput.FieldNameInSnakeCase.JsonOutput -Required.JsonInput.FieldNameWithMixedCases.JsonOutput -Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput -Required.JsonInput.FieldNameWithMixedCases.Validator -Required.JsonInput.OriginalProtoFieldName.JsonOutput diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs index 261ac6a7..302f8143 100644 --- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs @@ -229,16 +229,16 @@ namespace Google.Protobuf [Test] [TestCase("foo_bar", "fooBar")] [TestCase("bananaBanana", "bananaBanana")] - [TestCase("BANANABanana", "bananaBanana")] + [TestCase("BANANABanana", "BANANABanana")] [TestCase("simple", "simple")] - [TestCase("ACTION_AND_ADVENTURE", "actionAndAdventure")] + [TestCase("ACTION_AND_ADVENTURE", "ACTIONANDADVENTURE")] [TestCase("action_and_adventure", "actionAndAdventure")] [TestCase("kFoo", "kFoo")] - [TestCase("HTTPServer", "httpServer")] - [TestCase("CLIENT", "client")] - public void ToCamelCase(string original, string expected) + [TestCase("HTTPServer", "HTTPServer")] + [TestCase("CLIENT", "CLIENT")] + public void ToJsonName(string original, string expected) { - Assert.AreEqual(expected, JsonFormatter.ToCamelCase(original)); + Assert.AreEqual(expected, JsonFormatter.ToJsonName(original)); } [Test] diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs index d8a814d9..bb1a361e 100644 --- a/csharp/src/Google.Protobuf/JsonFormatter.cs +++ b/csharp/src/Google.Protobuf/JsonFormatter.cs @@ -248,87 +248,25 @@ namespace Google.Protobuf return !first; } - /// <summary> - /// Camel-case converter with added strictness for field mask formatting. - /// </summary> - /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception> - private static string ToCamelCaseForFieldMask(string input) + // Converted from java/core/src/main/java/com/google/protobuf/Descriptors.java + internal static string ToJsonName(string name) { - for (int i = 0; i < input.Length; i++) + StringBuilder result = new StringBuilder(name.Length); + bool isNextUpperCase = false; + foreach (char ch in name) { - char c = input[i]; - if (c >= 'A' && c <= 'Z') + if (ch == '_') { - throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}"); + isNextUpperCase = true; } - if (c == '_' && i < input.Length - 1) - { - char next = input[i + 1]; - if (next < 'a' || next > 'z') - { - throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}"); - } - } - } - return ToCamelCase(input); - } - - // Converted from src/google/protobuf/util/internal/utility.cc ToCamelCase - internal static string ToCamelCase(string input) - { - bool capitalizeNext = false; - bool wasCap = true; - bool isCap = false; - bool firstWord = true; - StringBuilder result = new StringBuilder(input.Length); - - for (int i = 0; i < input.Length; i++, wasCap = isCap) - { - isCap = char.IsUpper(input[i]); - if (input[i] == '_') + else if (isNextUpperCase) { - capitalizeNext = true; - if (result.Length != 0) - { - firstWord = false; - } - continue; - } - else if (firstWord) - { - // Consider when the current character B is capitalized, - // first word ends when: - // 1) following a lowercase: "...aB..." - // 2) followed by a lowercase: "...ABc..." - if (result.Length != 0 && isCap && - (!wasCap || (i + 1 < input.Length && char.IsLower(input[i + 1])))) - { - firstWord = false; - result.Append(input[i]); - } - else - { - result.Append(char.ToLowerInvariant(input[i])); - continue; - } - } - else if (capitalizeNext) - { - capitalizeNext = false; - if (char.IsLower(input[i])) - { - result.Append(char.ToUpperInvariant(input[i])); - continue; - } - else - { - result.Append(input[i]); - continue; - } + result.Append(char.ToUpperInvariant(ch)); + isNextUpperCase = false; } else { - result.Append(char.ToLowerInvariant(input[i])); + result.Append(ch); } } return result.ToString(); diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs index 6c6f6ee0..ed15d0e1 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs @@ -97,7 +97,7 @@ namespace Google.Protobuf.Reflection // We could trust the generated code and check whether the type of the property is // a MapField, but that feels a tad nasty. this.propertyName = propertyName; - JsonName = Proto.JsonName == "" ? JsonFormatter.ToCamelCase(Proto.Name) : Proto.JsonName; + JsonName = Proto.JsonName == "" ? JsonFormatter.ToJsonName(Proto.Name) : Proto.JsonName; } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs index f9cdb8af..0685c21a 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs @@ -52,7 +52,7 @@ namespace Google.Protobuf.WellKnownTypes /// </remarks> /// <param name="paths">Paths in the field mask</param> /// <param name="diagnosticOnly">Determines the handling of non-normalized values</param> - /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception> + /// <exception cref="InvalidOperationException">The represented field mask is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception> internal static string ToJson(IList<string> paths, bool diagnosticOnly) { var firstInvalid = paths.FirstOrDefault(p => !ValidatePath(p)); @@ -60,10 +60,10 @@ namespace Google.Protobuf.WellKnownTypes { var writer = new StringWriter(); #if DOTNET35 - var query = paths.Select(JsonFormatter.ToCamelCase); + var query = paths.Select(JsonFormatter.ToJsonName); JsonFormatter.WriteString(writer, string.Join(",", query.ToArray())); #else - JsonFormatter.WriteString(writer, string.Join(",", paths.Select(JsonFormatter.ToCamelCase))); + JsonFormatter.WriteString(writer, string.Join(",", paths.Select(JsonFormatter.ToJsonName))); #endif return writer.ToString(); } @@ -85,9 +85,9 @@ namespace Google.Protobuf.WellKnownTypes } /// <summary> - /// Camel-case converter with added strictness for field mask formatting. + /// Checks whether the given path is valid for a field mask. /// </summary> - /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception> + /// <returns>true if the path is valid; false otherwise</returns> private static bool ValidatePath(string input) { for (int i = 0; i < input.Length; i++) diff --git a/docs/third_party.md b/docs/third_party.md index 8ec551db..161bc3ca 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -83,6 +83,7 @@ These are projects we know about implementing Protocol Buffers for other program * Scala: https://github.com/SandroGrzicic/ScalaBuff * Scala: http://trueaccord.github.io/ScalaPB/ * Swift: https://github.com/alexeyxo/protobuf-swift +* Swift: https://github.com/apple/swift-protobuf/ * Vala: https://launchpad.net/protobuf-vala * Visual Basic: http://code.google.com/p/protobuf-net/ diff --git a/objectivec/GPBMessage.h b/objectivec/GPBMessage.h index 0cb74f9f..c07ec888 100644 --- a/objectivec/GPBMessage.h +++ b/objectivec/GPBMessage.h @@ -65,9 +65,18 @@ CF_EXTERN_C_END /** * Base class that each generated message subclasses from. + * + * @note While the class support NSSecureCoding, if the message has any + * extensions, they will end up reloaded in @c unknownFields as there is + * no way for the @c NSCoding plumbing to pass through a + * @c GPBExtensionRegistry. To support extensions, instead of passing the + * calls off to the Message, simple store the result of @c data, and then + * when loading, fetch the data and use + * @c +parseFromData:extensionRegistry:error: to provide an extension + * registry. **/ @interface GPBMessage : NSObject<NSSecureCoding, NSCopying> - + // If you add an instance method/property to this class that may conflict with // fields declared in protos, you need to update objective_helpers.cc. The main // cases are methods that take no arguments, or setFoo:/hasFoo: type methods. diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index 82bb3427..1cc932dd 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -61,7 +61,7 @@ namespace compiler { // comma-separated string. string CommaSeparatedList(const vector<const FileDescriptor*> all_files) { vector<string> names; - for (int i = 0; i < all_files.size(); i++) { + for (size_t i = 0; i < all_files.size(); i++) { names.push_back(all_files[i]->name()); } return Join(names, ","); @@ -97,7 +97,7 @@ void MockCodeGenerator::ExpectGenerated( while (!lines.empty() && lines.back().empty()) { lines.pop_back(); } - for (int i = 0; i < lines.size(); i++) { + for (size_t i = 0; i < lines.size(); i++) { lines[i] += "\n"; } @@ -114,7 +114,7 @@ void MockCodeGenerator::ExpectGenerated( EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]); EXPECT_EQ(kSecondInsertionPoint, lines[2 + insertion_list.size() * 2]); - for (int i = 0; i < insertion_list.size(); i++) { + for (size_t i = 0; i < insertion_list.size(); i++) { EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert", file, file, first_message_name), lines[1 + i]); @@ -170,7 +170,7 @@ bool MockCodeGenerator::Generate( SplitStringUsing(StripPrefixString(parameter, "insert="), ",", &insert_into); - for (int i = 0; i < insert_into.size(); i++) { + for (size_t i = 0; i < insert_into.size(); i++) { { google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert( GetOutputFileName(insert_into[i], file), kFirstInsertionPointName)); diff --git a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h index 7314ee4f..7f17b30d 100644 --- a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h +++ b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h @@ -38,7 +38,7 @@ namespace internal { inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, Atomic32 new_value) { - __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __atomic_compare_exchange_n(ptr, &old_value, new_value, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); return old_value; } @@ -61,7 +61,7 @@ inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, Atomic32 new_value) { - __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __atomic_compare_exchange_n(ptr, &old_value, new_value, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); return old_value; } @@ -69,7 +69,7 @@ inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, Atomic32 new_value) { - __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __atomic_compare_exchange_n(ptr, &old_value, new_value, false, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE); return old_value; } @@ -115,7 +115,7 @@ inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, Atomic64 old_value, Atomic64 new_value) { - __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __atomic_compare_exchange_n(ptr, &old_value, new_value, false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); return old_value; } @@ -123,7 +123,7 @@ inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, Atomic64 old_value, Atomic64 new_value) { - __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __atomic_compare_exchange_n(ptr, &old_value, new_value, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); return old_value; } |