aboutsummaryrefslogtreecommitdiff
path: root/csharp/src/Google.Protobuf/JsonParser.cs
diff options
context:
space:
mode:
Diffstat (limited to 'csharp/src/Google.Protobuf/JsonParser.cs')
-rw-r--r--csharp/src/Google.Protobuf/JsonParser.cs64
1 files changed, 53 insertions, 11 deletions
diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs
index 80d3013d..284bce93 100644
--- a/csharp/src/Google.Protobuf/JsonParser.cs
+++ b/csharp/src/Google.Protobuf/JsonParser.cs
@@ -86,7 +86,8 @@ namespace Google.Protobuf
{ FloatValue.Descriptor.FullName, MergeWrapperField },
{ DoubleValue.Descriptor.FullName, MergeWrapperField },
{ BytesValue.Descriptor.FullName, MergeWrapperField },
- { StringValue.Descriptor.FullName, MergeWrapperField }
+ { StringValue.Descriptor.FullName, MergeWrapperField },
+ { BoolValue.Descriptor.FullName, MergeWrapperField }
};
// Convenience method to avoid having to repeat the same code multiple times in the above
@@ -202,10 +203,14 @@ namespace Google.Protobuf
}
else
{
- // TODO: Is this what we want to do? If not, we'll need to skip the value,
- // which may be an object or array. (We might want to put code in the tokenizer
- // to do that.)
- throw new InvalidProtocolBufferException("Unknown field: " + name);
+ if (settings.IgnoreUnknownFields)
+ {
+ tokenizer.SkipValue();
+ }
+ else
+ {
+ throw new InvalidProtocolBufferException("Unknown field: " + name);
+ }
}
}
}
@@ -259,11 +264,12 @@ namespace Google.Protobuf
return;
}
tokenizer.PushBack(token);
- if (token.Type == JsonToken.TokenType.Null)
+ object value = ParseSingleValue(field, tokenizer);
+ if (value == null)
{
throw new InvalidProtocolBufferException("Repeated field elements cannot be null");
}
- list.Add(ParseSingleValue(field, tokenizer));
+ list.Add(value);
}
}
@@ -513,7 +519,7 @@ namespace Google.Protobuf
throw new InvalidProtocolBufferException("Expected string value for Any.@type");
}
string typeUrl = token.StringValue;
- string typeName = JsonFormatter.GetTypeName(typeUrl);
+ string typeName = Any.GetTypeName(typeUrl);
MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
if (descriptor == null)
@@ -996,6 +1002,19 @@ namespace Google.Protobuf
public TypeRegistry TypeRegistry { get; }
/// <summary>
+ /// Whether the parser should ignore unknown fields (<c>true</c>) or throw an exception when
+ /// they are encountered (<c>false</c>).
+ /// </summary>
+ public bool IgnoreUnknownFields { get; }
+
+ private Settings(int recursionLimit, TypeRegistry typeRegistry, bool ignoreUnknownFields)
+ {
+ RecursionLimit = recursionLimit;
+ TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
+ IgnoreUnknownFields = ignoreUnknownFields;
+ }
+
+ /// <summary>
/// Creates a new <see cref="Settings"/> object with the specified recursion limit.
/// </summary>
/// <param name="recursionLimit">The maximum depth of messages to parse</param>
@@ -1008,11 +1027,34 @@ namespace Google.Protobuf
/// </summary>
/// <param name="recursionLimit">The maximum depth of messages to parse</param>
/// <param name="typeRegistry">The type registry used to parse <see cref="Any"/> messages</param>
- public Settings(int recursionLimit, TypeRegistry typeRegistry)
+ public Settings(int recursionLimit, TypeRegistry typeRegistry) : this(recursionLimit, typeRegistry, false)
{
- RecursionLimit = recursionLimit;
- TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
}
+
+ /// <summary>
+ /// Creates a new <see cref="Settings"/> object set to either ignore unknown fields, or throw an exception
+ /// when unknown fields are encountered.
+ /// </summary>
+ /// <param name="ignoreUnknownFields"><c>true</c> if unknown fields should be ignored when parsing; <c>false</c> to throw an exception.</param>
+ public Settings WithIgnoreUnknownFields(bool ignoreUnknownFields) =>
+ new Settings(RecursionLimit, TypeRegistry, ignoreUnknownFields);
+
+ /// <summary>
+ /// Creates a new <see cref="Settings"/> object based on this one, but with the specified recursion limit.
+ /// </summary>
+ /// <param name="recursionLimit">The new recursion limit.</param>
+ public Settings WithRecursionLimit(int recursionLimit) =>
+ new Settings(recursionLimit, TypeRegistry, IgnoreUnknownFields);
+
+ /// <summary>
+ /// Creates a new <see cref="Settings"/> object based on this one, but with the specified type registry.
+ /// </summary>
+ /// <param name="typeRegistry">The new type registry. Must not be null.</param>
+ public Settings WithTypeRegistry(TypeRegistry typeRegistry) =>
+ new Settings(
+ RecursionLimit,
+ ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry)),
+ IgnoreUnknownFields);
}
}
}