コード例 #1
0
        /// <summary>
        /// Returns the detected kind of a serialized sentinel value, or None if it's not a sentinel value.
        /// </summary>
        /// <param name="value">The serialized value to inspect.</param>
        /// <returns>The kind of sentinel serialized in <paramref name="value"/> or None if it's not a sentinel value.</returns>
        internal static SentinelKind GetKind(Value value)
        {
            // If it's not a null value to start with, fetching NullValue returns NullValue.None
            // so we'll drop out to the right place.
            SentinelKind sentinelKind = (SentinelKind)value.NullValue;

            return(sentinelKind > SentinelKind.None && sentinelKind <= s_maxSentinelKind
                ? sentinelKind : SentinelKind.None);
        }
コード例 #2
0
        internal static SentinelValue ForArrayValue(SentinelKind sentinelKind, object[] values)
        {
            GaxPreconditions.CheckNotNull(values, nameof(values));
            ArrayValue array = ValueSerializer.Serialize(values).ArrayValue;

            // This is just checking that the simple approach we've taken in the previous line
            // really did what we expect.
            GaxPreconditions.CheckState(array != null, "Input wasn't serialized as an array");
            AugmentedValue augmented = new AugmentedValue {
                Kind = sentinelKind, Array = array
            };

            return(new SentinelValue(augmented));
        }
コード例 #3
0
        /// <summary>
        /// Finds all the sentinel values in a field map.
        /// Additionally, this validates that no sentinels exist in arrays (even nested).
        /// </summary>
        /// <param name="fields">The field map to find sentinels within.</param>
        /// <returns>The sentinel fields in the field map: both the value and the corresponding field path.</returns>
        private static List <SentinelField> FindSentinels(IDictionary <string, Value> fields)
        {
            List <SentinelField> result = new List <SentinelField>();

            FindSentinelsRecursively(fields, FieldPath.Empty);
            return(result);

            void FindSentinelsRecursively(IDictionary <string, Value> currentFields, FieldPath currentParentPath)
            {
                foreach (var pair in currentFields)
                {
                    Value        value        = pair.Value;
                    string       key          = pair.Key;
                    SentinelKind sentinelKind = SentinelValue.GetKind(value);
                    if (sentinelKind != SentinelKind.None)
                    {
                        result.Add(new SentinelField(currentParentPath.Append(key), value));
                    }
                    else if (value.MapValue != null)
                    {
                        FindSentinelsRecursively(value.MapValue.Fields, currentParentPath.Append(pair.Key));
                    }
                    else if (value.ArrayValue != null)
                    {
                        ValidateNoSentinelValues(value.ArrayValue.Values);
                    }
                }
            }

            void ValidateNoSentinelValues(IEnumerable <Value> values)
            {
                foreach (var value in values)
                {
                    if (SentinelValue.GetKind(value) != SentinelKind.None)
                    {
                        // We don't know what parameter name to use here
                        throw new ArgumentException("Sentinel values must not appear directly or indirectly within array values");
                    }
                    else if (value.MapValue != null)
                    {
                        ValidateNoSentinelValues(value.MapValue.Fields.Values);
                    }
                    else if (value.ArrayValue != null)
                    {
                        ValidateNoSentinelValues(value.ArrayValue.Values);
                    }
                }
            }
        }
コード例 #4
0
        internal static SentinelValue ForArrayValue(SerializationContext context, SentinelKind sentinelKind, object[] values)
        {
            GaxPreconditions.CheckNotNull(values, nameof(values));
            ArrayValue array = ValueSerializer.Serialize(context, values).ArrayValue;

            // This is just checking that the simple approach we've taken in the previous line
            // really did what we expect.
            GaxPreconditions.CheckState(array != null, "Input wasn't serialized as an array");
            GaxPreconditions.CheckState(!array.Values.Any(FindNestedSentinels), "Sentinel values cannot be nested in array union/remove values.");
            AugmentedValue augmented = new AugmentedValue {
                Kind = sentinelKind, Array = array
            };

            return(new SentinelValue(augmented));
        }
コード例 #5
0
        // There will be other sentinels with more parameters.

        private SentinelValue(SentinelKind kind, Func <Value> protoFactory)
        {
            Kind          = kind;
            _protoFactory = protoFactory;
        }