/// <summary> /// Gets the value of the specified extension /// </summary> public static TValue Get <TTarget, TValue>(ref ExtensionSet <TTarget> set, Extension <TTarget, TValue> extension) where TTarget : IExtendableMessage <TTarget> { IExtensionValue value; if (GetValue(ref set, extension, out value)) { return(((ExtensionValue <TValue>)value).GetValue()); } else { return(extension.DefaultValue); } }
/// <summary> /// Gets the value of the specified repeated extension or null if it doesn't exist in this set /// </summary> public static RepeatedField <TValue> Get <TTarget, TValue>(ref ExtensionSet <TTarget> set, RepeatedExtension <TTarget, TValue> extension) where TTarget : IExtendableMessage <TTarget> { IExtensionValue value; if (TryGetValue(ref set, extension, out value)) { return(((RepeatedExtensionValue <TValue>)value).GetValue()); } else { return(null); } }
/// <summary> /// Gets whether the value of the specified extension is set /// </summary> public static bool Has <TTarget, TValue>(ref ExtensionSet <TTarget> set, Extension <TTarget, TValue> extension) where TTarget : IExtendableMessage <TTarget> { IExtensionValue value; if (GetValue(ref set, extension, out value)) { return(((ExtensionValue <TValue>)value).HasValue); } else { return(false); } }
/// <summary> /// Clones the set into a new set. If the set is null, this returns null /// </summary> public static ExtensionSet <TTarget> Clone <TTarget>(ExtensionSet <TTarget> set) where TTarget : IExtendableMessage <TTarget> { if (set == null) { return(null); } var newSet = new ExtensionSet <TTarget>(); foreach (var pair in set.ValuesByNumber) { var cloned = pair.Value.Clone(); newSet.ValuesByNumber[pair.Key] = cloned; } return(newSet); }
/// <summary> /// Gets the value of the specified extension /// </summary> public static TValue Get <TTarget, TValue>(ref ExtensionSet <TTarget> set, Extension <TTarget, TValue> extension) where TTarget : IExtendableMessage <TTarget> { IExtensionValue value; if (TryGetValue(ref set, extension, out value)) { // The stored ExtensionValue can be a different type to what is being requested. // This happens when the same extension proto is compiled in different assemblies. // To allow consuming assemblies to still get the value when the TValue type is // different, this get method: // 1. Attempts to cast the value to the expected ExtensionValue<TValue>. // This is the usual case. It is used first because it avoids possibly boxing the value. // 2. Fallback to get the value as object from IExtensionValue then casting. // This allows for someone to specify a TValue of object. They can then convert // the values to bytes and reparse using expected value. // 3. If neither of these work, throw a user friendly error that the types aren't compatible. if (value is ExtensionValue <TValue> extensionValue) { return(extensionValue.GetValue()); } else if (value.GetValue() is TValue underlyingValue) { return(underlyingValue); } else { var valueType = value.GetType().GetTypeInfo(); if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(ExtensionValue <>)) { var storedType = valueType.GenericTypeArguments[0]; throw new InvalidOperationException( "The stored extension value has a type of '" + storedType.AssemblyQualifiedName + "'. " + "This a different from the requested type of '" + typeof(TValue).AssemblyQualifiedName + "'."); } else { throw new InvalidOperationException("Unexpected extension value type: " + valueType.AssemblyQualifiedName); } } } else { return(extension.DefaultValue); } }
public void TryMergeFieldFrom_CodedInputStream() { var message = new TestAllExtensions(); message.SetExtension(OptionalStringExtension, "abcd"); var input = new CodedInputStream(message.ToByteArray()); input.ExtensionRegistry = new ExtensionRegistry { OptionalStringExtension }; input.ReadTag(); // TryMergeFieldFrom expects that a tag was just read and will inspect the LastTag value ExtensionSet <TestAllExtensions> extensionSet = null; // test the legacy overload of TryMergeFieldFrom that takes a CodedInputStream Assert.IsTrue(ExtensionSet.TryMergeFieldFrom(ref extensionSet, input)); Assert.AreEqual("abcd", ExtensionSet.Get(ref extensionSet, OptionalStringExtension)); }
/// <summary> /// Gets the value of the specified repeated extension, registering it if it doesn't exist /// </summary> public static RepeatedField <TValue> GetOrRegister <TTarget, TValue>(ref ExtensionSet <TTarget> set, RepeatedExtension <TTarget, TValue> extension) where TTarget : IExtendableMessage <TTarget> { IExtensionValue value; if (set == null) { value = extension.CreateValue(); set = new ExtensionSet <TTarget>(); set.ValuesByNumber.Add(extension.FieldNumber, value); } else { if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value)) { value = extension.CreateValue(); set.ValuesByNumber.Add(extension.FieldNumber, value); } } return(((RepeatedExtensionValue <TValue>)value).GetValue()); }
/// <summary> /// Sets the value of the specified extension /// </summary> public static void Set <TTarget, TValue>(ref ExtensionSet <TTarget> set, Extension <TTarget, TValue> extension, TValue value) where TTarget : IExtendableMessage <TTarget> { IExtensionValue extensionValue; if (set == null) { extensionValue = extension.CreateValue(); set = new ExtensionSet <TTarget>(); set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); } else { if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out extensionValue)) { extensionValue = extension.CreateValue(); set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); } } ((ExtensionValue <TValue>)extensionValue).SetValue(value); }
/// <summary> /// Sets the value of the specified extension. This will make a new instance of ExtensionSet if the set is null. /// </summary> public static void Set <TTarget, TValue>(ref ExtensionSet <TTarget> set, Extension <TTarget, TValue> extension, TValue value) where TTarget : IExtendableMessage <TTarget> { ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value)); IExtensionValue extensionValue; if (set == null) { extensionValue = extension.CreateValue(); set = new ExtensionSet <TTarget>(); set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); } else { if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out extensionValue)) { extensionValue = extension.CreateValue(); set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); } } ((ExtensionValue <TValue>)extensionValue).SetValue(value); }
/// <summary> /// Merges the second set into the first set, creating a new instance if first is null /// </summary> public static void MergeFrom <TTarget>(ref ExtensionSet <TTarget> first, ExtensionSet <TTarget> second) where TTarget : IExtendableMessage <TTarget> { if (second == null) { return; } if (first == null) { first = new ExtensionSet <TTarget>(); } foreach (var pair in second.ValuesByNumber) { IExtensionValue value; if (first.ValuesByNumber.TryGetValue(pair.Key, out value)) { value.MergeFrom(pair.Value); } else { var cloned = pair.Value.Clone(); first.ValuesByNumber[pair.Key] = cloned; } } }
public void EmptyExtensionSet() { ExtensionSet <TestAllExtensions> extensions = new ExtensionSet <TestAllExtensions>(); Assert.AreEqual(0, extensions.CalculateSize()); }
/// <summary> /// Gets whether the value of the specified extension is set /// </summary> public static bool Has <TTarget, TValue>(ref ExtensionSet <TTarget> set, Extension <TTarget, TValue> extension) where TTarget : IExtendableMessage <TTarget> { IExtensionValue value; return(TryGetValue(ref set, extension, out value)); }