1ffe3c632Sopenharmony_ci#region Copyright notice and license 2ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format 3ffe3c632Sopenharmony_ci// Copyright 2008 Google Inc. All rights reserved. 4ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/ 5ffe3c632Sopenharmony_ci// 6ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 7ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are 8ffe3c632Sopenharmony_ci// met: 9ffe3c632Sopenharmony_ci// 10ffe3c632Sopenharmony_ci// * Redistributions of source code must retain the above copyright 11ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer. 12ffe3c632Sopenharmony_ci// * Redistributions in binary form must reproduce the above 13ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer 14ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the 15ffe3c632Sopenharmony_ci// distribution. 16ffe3c632Sopenharmony_ci// * Neither the name of Google Inc. nor the names of its 17ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from 18ffe3c632Sopenharmony_ci// this software without specific prior written permission. 19ffe3c632Sopenharmony_ci// 20ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31ffe3c632Sopenharmony_ci#endregion 32ffe3c632Sopenharmony_ci 33ffe3c632Sopenharmony_ciusing System; 34ffe3c632Sopenharmony_ciusing System.Collections; 35ffe3c632Sopenharmony_ciusing System.Collections.Generic; 36ffe3c632Sopenharmony_ciusing System.Linq; 37ffe3c632Sopenharmony_ci 38ffe3c632Sopenharmony_cinamespace Google.Protobuf 39ffe3c632Sopenharmony_ci{ 40ffe3c632Sopenharmony_ci /// <summary> 41ffe3c632Sopenharmony_ci /// Provides extensions to messages while parsing. This API is experimental and subject to change. 42ffe3c632Sopenharmony_ci /// </summary> 43ffe3c632Sopenharmony_ci public sealed class ExtensionRegistry : ICollection<Extension>, IDeepCloneable<ExtensionRegistry> 44ffe3c632Sopenharmony_ci { 45ffe3c632Sopenharmony_ci internal sealed class ExtensionComparer : IEqualityComparer<Extension> 46ffe3c632Sopenharmony_ci { 47ffe3c632Sopenharmony_ci public bool Equals(Extension a, Extension b) 48ffe3c632Sopenharmony_ci { 49ffe3c632Sopenharmony_ci return new ObjectIntPair<Type>(a.TargetType, a.FieldNumber).Equals(new ObjectIntPair<Type>(b.TargetType, b.FieldNumber)); 50ffe3c632Sopenharmony_ci } 51ffe3c632Sopenharmony_ci public int GetHashCode(Extension a) 52ffe3c632Sopenharmony_ci { 53ffe3c632Sopenharmony_ci return new ObjectIntPair<Type>(a.TargetType, a.FieldNumber).GetHashCode(); 54ffe3c632Sopenharmony_ci } 55ffe3c632Sopenharmony_ci 56ffe3c632Sopenharmony_ci internal static ExtensionComparer Instance = new ExtensionComparer(); 57ffe3c632Sopenharmony_ci } 58ffe3c632Sopenharmony_ci private IDictionary<ObjectIntPair<Type>, Extension> extensions; 59ffe3c632Sopenharmony_ci 60ffe3c632Sopenharmony_ci /// <summary> 61ffe3c632Sopenharmony_ci /// Creates a new empty extension registry 62ffe3c632Sopenharmony_ci /// </summary> 63ffe3c632Sopenharmony_ci public ExtensionRegistry() 64ffe3c632Sopenharmony_ci { 65ffe3c632Sopenharmony_ci extensions = new Dictionary<ObjectIntPair<Type>, Extension>(); 66ffe3c632Sopenharmony_ci } 67ffe3c632Sopenharmony_ci 68ffe3c632Sopenharmony_ci private ExtensionRegistry(IDictionary<ObjectIntPair<Type>, Extension> collection) 69ffe3c632Sopenharmony_ci { 70ffe3c632Sopenharmony_ci extensions = collection.ToDictionary(k => k.Key, v => v.Value); 71ffe3c632Sopenharmony_ci } 72ffe3c632Sopenharmony_ci 73ffe3c632Sopenharmony_ci /// <summary> 74ffe3c632Sopenharmony_ci /// Gets the total number of extensions in this extension registry 75ffe3c632Sopenharmony_ci /// </summary> 76ffe3c632Sopenharmony_ci public int Count => extensions.Count; 77ffe3c632Sopenharmony_ci 78ffe3c632Sopenharmony_ci /// <summary> 79ffe3c632Sopenharmony_ci /// Returns whether the registry is readonly 80ffe3c632Sopenharmony_ci /// </summary> 81ffe3c632Sopenharmony_ci bool ICollection<Extension>.IsReadOnly => false; 82ffe3c632Sopenharmony_ci 83ffe3c632Sopenharmony_ci internal bool ContainsInputField(uint lastTag, Type target, out Extension extension) 84ffe3c632Sopenharmony_ci { 85ffe3c632Sopenharmony_ci return extensions.TryGetValue(new ObjectIntPair<Type>(target, WireFormat.GetTagFieldNumber(lastTag)), out extension); 86ffe3c632Sopenharmony_ci } 87ffe3c632Sopenharmony_ci 88ffe3c632Sopenharmony_ci /// <summary> 89ffe3c632Sopenharmony_ci /// Adds the specified extension to the registry 90ffe3c632Sopenharmony_ci /// </summary> 91ffe3c632Sopenharmony_ci public void Add(Extension extension) 92ffe3c632Sopenharmony_ci { 93ffe3c632Sopenharmony_ci ProtoPreconditions.CheckNotNull(extension, nameof(extension)); 94ffe3c632Sopenharmony_ci 95ffe3c632Sopenharmony_ci extensions.Add(new ObjectIntPair<Type>(extension.TargetType, extension.FieldNumber), extension); 96ffe3c632Sopenharmony_ci } 97ffe3c632Sopenharmony_ci 98ffe3c632Sopenharmony_ci /// <summary> 99ffe3c632Sopenharmony_ci /// Adds the specified extensions to the registry 100ffe3c632Sopenharmony_ci /// </summary> 101ffe3c632Sopenharmony_ci public void AddRange(IEnumerable<Extension> extensions) 102ffe3c632Sopenharmony_ci { 103ffe3c632Sopenharmony_ci ProtoPreconditions.CheckNotNull(extensions, nameof(extensions)); 104ffe3c632Sopenharmony_ci 105ffe3c632Sopenharmony_ci foreach (var extension in extensions) 106ffe3c632Sopenharmony_ci { 107ffe3c632Sopenharmony_ci Add(extension); 108ffe3c632Sopenharmony_ci } 109ffe3c632Sopenharmony_ci } 110ffe3c632Sopenharmony_ci 111ffe3c632Sopenharmony_ci /// <summary> 112ffe3c632Sopenharmony_ci /// Clears the registry of all values 113ffe3c632Sopenharmony_ci /// </summary> 114ffe3c632Sopenharmony_ci public void Clear() 115ffe3c632Sopenharmony_ci { 116ffe3c632Sopenharmony_ci extensions.Clear(); 117ffe3c632Sopenharmony_ci } 118ffe3c632Sopenharmony_ci 119ffe3c632Sopenharmony_ci /// <summary> 120ffe3c632Sopenharmony_ci /// Gets whether the extension registry contains the specified extension 121ffe3c632Sopenharmony_ci /// </summary> 122ffe3c632Sopenharmony_ci public bool Contains(Extension item) 123ffe3c632Sopenharmony_ci { 124ffe3c632Sopenharmony_ci ProtoPreconditions.CheckNotNull(item, nameof(item)); 125ffe3c632Sopenharmony_ci 126ffe3c632Sopenharmony_ci return extensions.ContainsKey(new ObjectIntPair<Type>(item.TargetType, item.FieldNumber)); 127ffe3c632Sopenharmony_ci } 128ffe3c632Sopenharmony_ci 129ffe3c632Sopenharmony_ci /// <summary> 130ffe3c632Sopenharmony_ci /// Copies the arrays in the registry set to the specified array at the specified index 131ffe3c632Sopenharmony_ci /// </summary> 132ffe3c632Sopenharmony_ci /// <param name="array">The array to copy to</param> 133ffe3c632Sopenharmony_ci /// <param name="arrayIndex">The array index to start at</param> 134ffe3c632Sopenharmony_ci void ICollection<Extension>.CopyTo(Extension[] array, int arrayIndex) 135ffe3c632Sopenharmony_ci { 136ffe3c632Sopenharmony_ci ProtoPreconditions.CheckNotNull(array, nameof(array)); 137ffe3c632Sopenharmony_ci if (arrayIndex < 0 || arrayIndex >= array.Length) 138ffe3c632Sopenharmony_ci { 139ffe3c632Sopenharmony_ci throw new ArgumentOutOfRangeException(nameof(arrayIndex)); 140ffe3c632Sopenharmony_ci } 141ffe3c632Sopenharmony_ci if (array.Length - arrayIndex < Count) 142ffe3c632Sopenharmony_ci { 143ffe3c632Sopenharmony_ci throw new ArgumentException("The provided array is shorter than the number of elements in the registry"); 144ffe3c632Sopenharmony_ci } 145ffe3c632Sopenharmony_ci 146ffe3c632Sopenharmony_ci for (int i = 0; i < array.Length; i++) 147ffe3c632Sopenharmony_ci { 148ffe3c632Sopenharmony_ci Extension extension = array[i]; 149ffe3c632Sopenharmony_ci extensions.Add(new ObjectIntPair<Type>(extension.TargetType, extension.FieldNumber), extension); 150ffe3c632Sopenharmony_ci } 151ffe3c632Sopenharmony_ci } 152ffe3c632Sopenharmony_ci 153ffe3c632Sopenharmony_ci /// <summary> 154ffe3c632Sopenharmony_ci /// Returns an enumerator to enumerate through the items in the registry 155ffe3c632Sopenharmony_ci /// </summary> 156ffe3c632Sopenharmony_ci /// <returns>Returns an enumerator for the extensions in this registry</returns> 157ffe3c632Sopenharmony_ci public IEnumerator<Extension> GetEnumerator() 158ffe3c632Sopenharmony_ci { 159ffe3c632Sopenharmony_ci return extensions.Values.GetEnumerator(); 160ffe3c632Sopenharmony_ci } 161ffe3c632Sopenharmony_ci 162ffe3c632Sopenharmony_ci /// <summary> 163ffe3c632Sopenharmony_ci /// Removes the specified extension from the set 164ffe3c632Sopenharmony_ci /// </summary> 165ffe3c632Sopenharmony_ci /// <param name="item">The extension</param> 166ffe3c632Sopenharmony_ci /// <returns><c>true</c> if the extension was removed, otherwise <c>false</c></returns> 167ffe3c632Sopenharmony_ci public bool Remove(Extension item) 168ffe3c632Sopenharmony_ci { 169ffe3c632Sopenharmony_ci ProtoPreconditions.CheckNotNull(item, nameof(item)); 170ffe3c632Sopenharmony_ci 171ffe3c632Sopenharmony_ci return extensions.Remove(new ObjectIntPair<Type>(item.TargetType, item.FieldNumber)); 172ffe3c632Sopenharmony_ci } 173ffe3c632Sopenharmony_ci 174ffe3c632Sopenharmony_ci IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 175ffe3c632Sopenharmony_ci 176ffe3c632Sopenharmony_ci /// <summary> 177ffe3c632Sopenharmony_ci /// Clones the registry into a new registry 178ffe3c632Sopenharmony_ci /// </summary> 179ffe3c632Sopenharmony_ci public ExtensionRegistry Clone() 180ffe3c632Sopenharmony_ci { 181ffe3c632Sopenharmony_ci return new ExtensionRegistry(extensions); 182ffe3c632Sopenharmony_ci } 183ffe3c632Sopenharmony_ci } 184ffe3c632Sopenharmony_ci} 185