1ffe3c632Sopenharmony_ci#region Copyright notice and license
2ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format
3ffe3c632Sopenharmony_ci// Copyright 2015 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.Generic;
35ffe3c632Sopenharmony_ciusing System.IO;
36ffe3c632Sopenharmony_ciusing System.Security;
37ffe3c632Sopenharmony_ciusing Google.Protobuf.Reflection;
38ffe3c632Sopenharmony_ci
39ffe3c632Sopenharmony_cinamespace Google.Protobuf
40ffe3c632Sopenharmony_ci{
41ffe3c632Sopenharmony_ci    /// <summary>
42ffe3c632Sopenharmony_ci    /// Used to keep track of fields which were seen when parsing a protocol message
43ffe3c632Sopenharmony_ci    /// but whose field numbers or types are unrecognized. This most frequently
44ffe3c632Sopenharmony_ci    /// occurs when new fields are added to a message type and then messages containing
45ffe3c632Sopenharmony_ci    /// those fields are read by old software that was built before the new types were
46ffe3c632Sopenharmony_ci    /// added.
47ffe3c632Sopenharmony_ci    ///
48ffe3c632Sopenharmony_ci    /// Most users will never need to use this class directly.
49ffe3c632Sopenharmony_ci    /// </summary>
50ffe3c632Sopenharmony_ci    public sealed partial class UnknownFieldSet
51ffe3c632Sopenharmony_ci    {
52ffe3c632Sopenharmony_ci        private readonly IDictionary<int, UnknownField> fields;
53ffe3c632Sopenharmony_ci
54ffe3c632Sopenharmony_ci        /// <summary>
55ffe3c632Sopenharmony_ci        /// Creates a new UnknownFieldSet.
56ffe3c632Sopenharmony_ci        /// </summary>
57ffe3c632Sopenharmony_ci        internal UnknownFieldSet()
58ffe3c632Sopenharmony_ci        {
59ffe3c632Sopenharmony_ci            this.fields = new Dictionary<int, UnknownField>();
60ffe3c632Sopenharmony_ci        }
61ffe3c632Sopenharmony_ci
62ffe3c632Sopenharmony_ci        /// <summary>
63ffe3c632Sopenharmony_ci        /// Checks whether or not the given field number is present in the set.
64ffe3c632Sopenharmony_ci        /// </summary>
65ffe3c632Sopenharmony_ci        internal bool HasField(int field)
66ffe3c632Sopenharmony_ci        {
67ffe3c632Sopenharmony_ci            return fields.ContainsKey(field);
68ffe3c632Sopenharmony_ci        }
69ffe3c632Sopenharmony_ci
70ffe3c632Sopenharmony_ci        /// <summary>
71ffe3c632Sopenharmony_ci        /// Serializes the set and writes it to <paramref name="output"/>.
72ffe3c632Sopenharmony_ci        /// </summary>
73ffe3c632Sopenharmony_ci        public void WriteTo(CodedOutputStream output)
74ffe3c632Sopenharmony_ci        {
75ffe3c632Sopenharmony_ci            WriteContext.Initialize(output, out WriteContext ctx);
76ffe3c632Sopenharmony_ci            try
77ffe3c632Sopenharmony_ci            {
78ffe3c632Sopenharmony_ci                WriteTo(ref ctx);
79ffe3c632Sopenharmony_ci            }
80ffe3c632Sopenharmony_ci            finally
81ffe3c632Sopenharmony_ci            {
82ffe3c632Sopenharmony_ci                ctx.CopyStateTo(output);
83ffe3c632Sopenharmony_ci            }
84ffe3c632Sopenharmony_ci        }
85ffe3c632Sopenharmony_ci
86ffe3c632Sopenharmony_ci        /// <summary>
87ffe3c632Sopenharmony_ci        /// Serializes the set and writes it to <paramref name="ctx"/>.
88ffe3c632Sopenharmony_ci        /// </summary>
89ffe3c632Sopenharmony_ci        [SecuritySafeCritical]
90ffe3c632Sopenharmony_ci        public void WriteTo(ref WriteContext ctx)
91ffe3c632Sopenharmony_ci        {
92ffe3c632Sopenharmony_ci            foreach (KeyValuePair<int, UnknownField> entry in fields)
93ffe3c632Sopenharmony_ci            {
94ffe3c632Sopenharmony_ci                entry.Value.WriteTo(entry.Key, ref ctx);
95ffe3c632Sopenharmony_ci            }
96ffe3c632Sopenharmony_ci        }
97ffe3c632Sopenharmony_ci
98ffe3c632Sopenharmony_ci        /// <summary>
99ffe3c632Sopenharmony_ci        /// Gets the number of bytes required to encode this set.
100ffe3c632Sopenharmony_ci        /// </summary>
101ffe3c632Sopenharmony_ci        public int CalculateSize()
102ffe3c632Sopenharmony_ci        {
103ffe3c632Sopenharmony_ci            int result = 0;
104ffe3c632Sopenharmony_ci            foreach (KeyValuePair<int, UnknownField> entry in fields)
105ffe3c632Sopenharmony_ci            {
106ffe3c632Sopenharmony_ci                result += entry.Value.GetSerializedSize(entry.Key);
107ffe3c632Sopenharmony_ci            }
108ffe3c632Sopenharmony_ci            return result;
109ffe3c632Sopenharmony_ci        }
110ffe3c632Sopenharmony_ci
111ffe3c632Sopenharmony_ci        /// <summary>
112ffe3c632Sopenharmony_ci        /// Checks if two unknown field sets are equal.
113ffe3c632Sopenharmony_ci        /// </summary>
114ffe3c632Sopenharmony_ci        public override bool Equals(object other)
115ffe3c632Sopenharmony_ci        {
116ffe3c632Sopenharmony_ci            if (ReferenceEquals(this, other))
117ffe3c632Sopenharmony_ci            {
118ffe3c632Sopenharmony_ci                return true;
119ffe3c632Sopenharmony_ci            }
120ffe3c632Sopenharmony_ci            UnknownFieldSet otherSet = other as UnknownFieldSet;
121ffe3c632Sopenharmony_ci            IDictionary<int, UnknownField> otherFields = otherSet.fields;
122ffe3c632Sopenharmony_ci            if (fields.Count  != otherFields.Count)
123ffe3c632Sopenharmony_ci            {
124ffe3c632Sopenharmony_ci                return false;
125ffe3c632Sopenharmony_ci            }
126ffe3c632Sopenharmony_ci            foreach (KeyValuePair<int, UnknownField> leftEntry in fields)
127ffe3c632Sopenharmony_ci            {
128ffe3c632Sopenharmony_ci                UnknownField rightValue;
129ffe3c632Sopenharmony_ci                if (!otherFields.TryGetValue(leftEntry.Key, out rightValue))
130ffe3c632Sopenharmony_ci                {
131ffe3c632Sopenharmony_ci                    return false;
132ffe3c632Sopenharmony_ci                }
133ffe3c632Sopenharmony_ci                if (!leftEntry.Value.Equals(rightValue))
134ffe3c632Sopenharmony_ci                {
135ffe3c632Sopenharmony_ci                    return false;
136ffe3c632Sopenharmony_ci                }
137ffe3c632Sopenharmony_ci            }
138ffe3c632Sopenharmony_ci            return true;
139ffe3c632Sopenharmony_ci        }
140ffe3c632Sopenharmony_ci
141ffe3c632Sopenharmony_ci        /// <summary>
142ffe3c632Sopenharmony_ci        /// Gets the unknown field set's hash code.
143ffe3c632Sopenharmony_ci        /// </summary>
144ffe3c632Sopenharmony_ci        public override int GetHashCode()
145ffe3c632Sopenharmony_ci        {
146ffe3c632Sopenharmony_ci            int ret = 1;
147ffe3c632Sopenharmony_ci            foreach (KeyValuePair<int, UnknownField> field in fields)
148ffe3c632Sopenharmony_ci            {
149ffe3c632Sopenharmony_ci                // Use ^ here to make the field order irrelevant.
150ffe3c632Sopenharmony_ci                int hash = field.Key.GetHashCode() ^ field.Value.GetHashCode();
151ffe3c632Sopenharmony_ci                ret ^= hash;
152ffe3c632Sopenharmony_ci            }
153ffe3c632Sopenharmony_ci            return ret;
154ffe3c632Sopenharmony_ci        }
155ffe3c632Sopenharmony_ci
156ffe3c632Sopenharmony_ci        // Optimization:  We keep around the last field that was
157ffe3c632Sopenharmony_ci        // modified so that we can efficiently add to it multiple times in a
158ffe3c632Sopenharmony_ci        // row (important when parsing an unknown repeated field).
159ffe3c632Sopenharmony_ci        private int lastFieldNumber;
160ffe3c632Sopenharmony_ci        private UnknownField lastField;
161ffe3c632Sopenharmony_ci
162ffe3c632Sopenharmony_ci        private UnknownField GetOrAddField(int number)
163ffe3c632Sopenharmony_ci        {
164ffe3c632Sopenharmony_ci            if (lastField != null && number == lastFieldNumber)
165ffe3c632Sopenharmony_ci            {
166ffe3c632Sopenharmony_ci                return lastField;
167ffe3c632Sopenharmony_ci            }
168ffe3c632Sopenharmony_ci            if (number == 0)
169ffe3c632Sopenharmony_ci            {
170ffe3c632Sopenharmony_ci                return null;
171ffe3c632Sopenharmony_ci            }
172ffe3c632Sopenharmony_ci
173ffe3c632Sopenharmony_ci            UnknownField existing;
174ffe3c632Sopenharmony_ci            if (fields.TryGetValue(number, out existing))
175ffe3c632Sopenharmony_ci            {
176ffe3c632Sopenharmony_ci                return existing;
177ffe3c632Sopenharmony_ci            }
178ffe3c632Sopenharmony_ci            lastField = new UnknownField();
179ffe3c632Sopenharmony_ci            AddOrReplaceField(number, lastField);
180ffe3c632Sopenharmony_ci            lastFieldNumber = number;
181ffe3c632Sopenharmony_ci            return lastField;
182ffe3c632Sopenharmony_ci        }
183ffe3c632Sopenharmony_ci
184ffe3c632Sopenharmony_ci        /// <summary>
185ffe3c632Sopenharmony_ci        /// Adds a field to the set. If a field with the same number already exists, it
186ffe3c632Sopenharmony_ci        /// is replaced.
187ffe3c632Sopenharmony_ci        /// </summary>
188ffe3c632Sopenharmony_ci        internal UnknownFieldSet AddOrReplaceField(int number, UnknownField field)
189ffe3c632Sopenharmony_ci        {
190ffe3c632Sopenharmony_ci            if (number == 0)
191ffe3c632Sopenharmony_ci            {
192ffe3c632Sopenharmony_ci                throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
193ffe3c632Sopenharmony_ci            }
194ffe3c632Sopenharmony_ci            fields[number] = field;
195ffe3c632Sopenharmony_ci            return this;
196ffe3c632Sopenharmony_ci        }
197ffe3c632Sopenharmony_ci
198ffe3c632Sopenharmony_ci        /// <summary>
199ffe3c632Sopenharmony_ci        /// Parse a single field from <paramref name="ctx"/> and merge it
200ffe3c632Sopenharmony_ci        /// into this set.
201ffe3c632Sopenharmony_ci        /// </summary>
202ffe3c632Sopenharmony_ci        /// <param name="ctx">The parse context from which to read the field</param>
203ffe3c632Sopenharmony_ci        /// <returns>false if the tag is an "end group" tag, true otherwise</returns>
204ffe3c632Sopenharmony_ci        private bool MergeFieldFrom(ref ParseContext ctx)
205ffe3c632Sopenharmony_ci        {
206ffe3c632Sopenharmony_ci            uint tag = ctx.LastTag;
207ffe3c632Sopenharmony_ci            int number = WireFormat.GetTagFieldNumber(tag);
208ffe3c632Sopenharmony_ci            switch (WireFormat.GetTagWireType(tag))
209ffe3c632Sopenharmony_ci            {
210ffe3c632Sopenharmony_ci                case WireFormat.WireType.Varint:
211ffe3c632Sopenharmony_ci                    {
212ffe3c632Sopenharmony_ci                        ulong uint64 = ctx.ReadUInt64();
213ffe3c632Sopenharmony_ci                        GetOrAddField(number).AddVarint(uint64);
214ffe3c632Sopenharmony_ci                        return true;
215ffe3c632Sopenharmony_ci                    }
216ffe3c632Sopenharmony_ci                case WireFormat.WireType.Fixed32:
217ffe3c632Sopenharmony_ci                    {
218ffe3c632Sopenharmony_ci                        uint uint32 = ctx.ReadFixed32();
219ffe3c632Sopenharmony_ci                        GetOrAddField(number).AddFixed32(uint32);
220ffe3c632Sopenharmony_ci                        return true;
221ffe3c632Sopenharmony_ci                    }
222ffe3c632Sopenharmony_ci                case WireFormat.WireType.Fixed64:
223ffe3c632Sopenharmony_ci                    {
224ffe3c632Sopenharmony_ci                        ulong uint64 = ctx.ReadFixed64();
225ffe3c632Sopenharmony_ci                        GetOrAddField(number).AddFixed64(uint64);
226ffe3c632Sopenharmony_ci                        return true;
227ffe3c632Sopenharmony_ci                    }
228ffe3c632Sopenharmony_ci                case WireFormat.WireType.LengthDelimited:
229ffe3c632Sopenharmony_ci                    {
230ffe3c632Sopenharmony_ci                        ByteString bytes = ctx.ReadBytes();
231ffe3c632Sopenharmony_ci                        GetOrAddField(number).AddLengthDelimited(bytes);
232ffe3c632Sopenharmony_ci                        return true;
233ffe3c632Sopenharmony_ci                    }
234ffe3c632Sopenharmony_ci                case WireFormat.WireType.StartGroup:
235ffe3c632Sopenharmony_ci                    {
236ffe3c632Sopenharmony_ci                        UnknownFieldSet set = new UnknownFieldSet();
237ffe3c632Sopenharmony_ci                        ParsingPrimitivesMessages.ReadGroup(ref ctx, number, set);
238ffe3c632Sopenharmony_ci                        GetOrAddField(number).AddGroup(set);
239ffe3c632Sopenharmony_ci                        return true;
240ffe3c632Sopenharmony_ci                    }
241ffe3c632Sopenharmony_ci                case WireFormat.WireType.EndGroup:
242ffe3c632Sopenharmony_ci                    {
243ffe3c632Sopenharmony_ci                        return false;
244ffe3c632Sopenharmony_ci                    }
245ffe3c632Sopenharmony_ci                default:
246ffe3c632Sopenharmony_ci                    throw InvalidProtocolBufferException.InvalidWireType();
247ffe3c632Sopenharmony_ci            }
248ffe3c632Sopenharmony_ci        }
249ffe3c632Sopenharmony_ci
250ffe3c632Sopenharmony_ci        internal void MergeGroupFrom(ref ParseContext ctx)
251ffe3c632Sopenharmony_ci        {
252ffe3c632Sopenharmony_ci            while (true)
253ffe3c632Sopenharmony_ci            {
254ffe3c632Sopenharmony_ci                uint tag = ctx.ReadTag();
255ffe3c632Sopenharmony_ci                if (tag == 0)
256ffe3c632Sopenharmony_ci                {
257ffe3c632Sopenharmony_ci                    break;
258ffe3c632Sopenharmony_ci                }
259ffe3c632Sopenharmony_ci                if (!MergeFieldFrom(ref ctx))
260ffe3c632Sopenharmony_ci                {
261ffe3c632Sopenharmony_ci                    break;
262ffe3c632Sopenharmony_ci                }
263ffe3c632Sopenharmony_ci            }
264ffe3c632Sopenharmony_ci        }
265ffe3c632Sopenharmony_ci
266ffe3c632Sopenharmony_ci        /// <summary>
267ffe3c632Sopenharmony_ci        /// Create a new UnknownFieldSet if unknownFields is null.
268ffe3c632Sopenharmony_ci        /// Parse a single field from <paramref name="input"/> and merge it
269ffe3c632Sopenharmony_ci        /// into unknownFields. If <paramref name="input"/> is configured to discard unknown fields,
270ffe3c632Sopenharmony_ci        /// <paramref name="unknownFields"/> will be returned as-is and the field will be skipped.
271ffe3c632Sopenharmony_ci        /// </summary>
272ffe3c632Sopenharmony_ci        /// <param name="unknownFields">The UnknownFieldSet which need to be merged</param>
273ffe3c632Sopenharmony_ci        /// <param name="input">The coded input stream containing the field</param>
274ffe3c632Sopenharmony_ci        /// <returns>The merged UnknownFieldSet</returns>
275ffe3c632Sopenharmony_ci        public static UnknownFieldSet MergeFieldFrom(UnknownFieldSet unknownFields,
276ffe3c632Sopenharmony_ci                                                     CodedInputStream input)
277ffe3c632Sopenharmony_ci        {
278ffe3c632Sopenharmony_ci            ParseContext.Initialize(input, out ParseContext ctx);
279ffe3c632Sopenharmony_ci            try
280ffe3c632Sopenharmony_ci            {
281ffe3c632Sopenharmony_ci                return MergeFieldFrom(unknownFields, ref ctx);
282ffe3c632Sopenharmony_ci            }
283ffe3c632Sopenharmony_ci            finally
284ffe3c632Sopenharmony_ci            {
285ffe3c632Sopenharmony_ci                ctx.CopyStateTo(input);
286ffe3c632Sopenharmony_ci            }
287ffe3c632Sopenharmony_ci        }
288ffe3c632Sopenharmony_ci
289ffe3c632Sopenharmony_ci        /// <summary>
290ffe3c632Sopenharmony_ci        /// Create a new UnknownFieldSet if unknownFields is null.
291ffe3c632Sopenharmony_ci        /// Parse a single field from <paramref name="ctx"/> and merge it
292ffe3c632Sopenharmony_ci        /// into unknownFields. If <paramref name="ctx"/> is configured to discard unknown fields,
293ffe3c632Sopenharmony_ci        /// <paramref name="unknownFields"/> will be returned as-is and the field will be skipped.
294ffe3c632Sopenharmony_ci        /// </summary>
295ffe3c632Sopenharmony_ci        /// <param name="unknownFields">The UnknownFieldSet which need to be merged</param>
296ffe3c632Sopenharmony_ci        /// <param name="ctx">The parse context from which to read the field</param>
297ffe3c632Sopenharmony_ci        /// <returns>The merged UnknownFieldSet</returns>
298ffe3c632Sopenharmony_ci        [SecuritySafeCritical]
299ffe3c632Sopenharmony_ci        public static UnknownFieldSet MergeFieldFrom(UnknownFieldSet unknownFields,
300ffe3c632Sopenharmony_ci                                                     ref ParseContext ctx)
301ffe3c632Sopenharmony_ci        {
302ffe3c632Sopenharmony_ci            if (ctx.DiscardUnknownFields)
303ffe3c632Sopenharmony_ci            {
304ffe3c632Sopenharmony_ci                ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state);
305ffe3c632Sopenharmony_ci                return unknownFields;
306ffe3c632Sopenharmony_ci            }
307ffe3c632Sopenharmony_ci            if (unknownFields == null)
308ffe3c632Sopenharmony_ci            {
309ffe3c632Sopenharmony_ci                unknownFields = new UnknownFieldSet();
310ffe3c632Sopenharmony_ci            }
311ffe3c632Sopenharmony_ci            if (!unknownFields.MergeFieldFrom(ref ctx))
312ffe3c632Sopenharmony_ci            {
313ffe3c632Sopenharmony_ci                throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); // match the old code-gen
314ffe3c632Sopenharmony_ci            }
315ffe3c632Sopenharmony_ci            return unknownFields;
316ffe3c632Sopenharmony_ci        }
317ffe3c632Sopenharmony_ci
318ffe3c632Sopenharmony_ci        /// <summary>
319ffe3c632Sopenharmony_ci        /// Merges the fields from <paramref name="other"/> into this set.
320ffe3c632Sopenharmony_ci        /// If a field number exists in both sets, the values in <paramref name="other"/>
321ffe3c632Sopenharmony_ci        /// will be appended to the values in this set.
322ffe3c632Sopenharmony_ci        /// </summary>
323ffe3c632Sopenharmony_ci        private UnknownFieldSet MergeFrom(UnknownFieldSet other)
324ffe3c632Sopenharmony_ci        {
325ffe3c632Sopenharmony_ci            if (other != null)
326ffe3c632Sopenharmony_ci            {
327ffe3c632Sopenharmony_ci                foreach (KeyValuePair<int, UnknownField> entry in other.fields)
328ffe3c632Sopenharmony_ci                {
329ffe3c632Sopenharmony_ci                    MergeField(entry.Key, entry.Value);
330ffe3c632Sopenharmony_ci                }
331ffe3c632Sopenharmony_ci            }
332ffe3c632Sopenharmony_ci            return this;
333ffe3c632Sopenharmony_ci        }
334ffe3c632Sopenharmony_ci
335ffe3c632Sopenharmony_ci        /// <summary>
336ffe3c632Sopenharmony_ci        /// Created a new UnknownFieldSet to <paramref name="unknownFields"/> if
337ffe3c632Sopenharmony_ci        /// needed and merges the fields from <paramref name="other"/> into the first set.
338ffe3c632Sopenharmony_ci        /// If a field number exists in both sets, the values in <paramref name="other"/>
339ffe3c632Sopenharmony_ci        /// will be appended to the values in this set.
340ffe3c632Sopenharmony_ci        /// </summary>
341ffe3c632Sopenharmony_ci        public static UnknownFieldSet MergeFrom(UnknownFieldSet unknownFields,
342ffe3c632Sopenharmony_ci                                                UnknownFieldSet other)
343ffe3c632Sopenharmony_ci        {
344ffe3c632Sopenharmony_ci            if (other == null)
345ffe3c632Sopenharmony_ci            {
346ffe3c632Sopenharmony_ci                return unknownFields;
347ffe3c632Sopenharmony_ci            }
348ffe3c632Sopenharmony_ci            if (unknownFields == null)
349ffe3c632Sopenharmony_ci            {
350ffe3c632Sopenharmony_ci                unknownFields = new UnknownFieldSet();
351ffe3c632Sopenharmony_ci            }
352ffe3c632Sopenharmony_ci            unknownFields.MergeFrom(other);
353ffe3c632Sopenharmony_ci            return unknownFields;
354ffe3c632Sopenharmony_ci        }
355ffe3c632Sopenharmony_ci
356ffe3c632Sopenharmony_ci
357ffe3c632Sopenharmony_ci        /// <summary>
358ffe3c632Sopenharmony_ci        /// Adds a field to the unknown field set. If a field with the same
359ffe3c632Sopenharmony_ci        /// number already exists, the two are merged.
360ffe3c632Sopenharmony_ci        /// </summary>
361ffe3c632Sopenharmony_ci        private UnknownFieldSet MergeField(int number, UnknownField field)
362ffe3c632Sopenharmony_ci        {
363ffe3c632Sopenharmony_ci            if (number == 0)
364ffe3c632Sopenharmony_ci            {
365ffe3c632Sopenharmony_ci                throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
366ffe3c632Sopenharmony_ci            }
367ffe3c632Sopenharmony_ci            if (HasField(number))
368ffe3c632Sopenharmony_ci            {
369ffe3c632Sopenharmony_ci                GetOrAddField(number).MergeFrom(field);
370ffe3c632Sopenharmony_ci            }
371ffe3c632Sopenharmony_ci            else
372ffe3c632Sopenharmony_ci            {
373ffe3c632Sopenharmony_ci                AddOrReplaceField(number, field);
374ffe3c632Sopenharmony_ci            }
375ffe3c632Sopenharmony_ci            return this;
376ffe3c632Sopenharmony_ci        }
377ffe3c632Sopenharmony_ci
378ffe3c632Sopenharmony_ci        /// <summary>
379ffe3c632Sopenharmony_ci        /// Clone an unknown field set from <paramref name="other"/>.
380ffe3c632Sopenharmony_ci        /// </summary>
381ffe3c632Sopenharmony_ci        public static UnknownFieldSet Clone(UnknownFieldSet other)
382ffe3c632Sopenharmony_ci        {
383ffe3c632Sopenharmony_ci            if (other == null)
384ffe3c632Sopenharmony_ci            {
385ffe3c632Sopenharmony_ci                return null;
386ffe3c632Sopenharmony_ci            }
387ffe3c632Sopenharmony_ci            UnknownFieldSet unknownFields = new UnknownFieldSet();
388ffe3c632Sopenharmony_ci            unknownFields.MergeFrom(other);
389ffe3c632Sopenharmony_ci            return unknownFields;
390ffe3c632Sopenharmony_ci        }
391ffe3c632Sopenharmony_ci    }
392ffe3c632Sopenharmony_ci}
393ffe3c632Sopenharmony_ci
394