Commit c07571a7 authored by csharptest's avatar csharptest Committed by unknown

Added copy of existing classes that will be made Lite

parent 57599ef1
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System.Collections.Generic;
using Google.ProtocolBuffers.Descriptors;
using System;
namespace Google.ProtocolBuffers {
/// <summary>
/// A table of known extensions, searchable by name or field number. When
/// parsing a protocol message that might have extensions, you must provide
/// an <see cref="ExtensionRegistry"/> in which you have registered any extensions
/// that you want to be able to parse. Otherwise, those extensions will just
/// be treated like unknown fields.
/// </summary>
/// <example>
/// For example, if you had the <c>.proto</c> file:
/// <code>
/// option java_class = "MyProto";
///
/// message Foo {
/// extensions 1000 to max;
/// }
///
/// extend Foo {
/// optional int32 bar;
/// }
/// </code>
///
/// Then you might write code like:
///
/// <code>
/// ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
/// registry.Add(MyProto.Bar);
/// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry);
/// </code>
/// </example>
///
/// <remarks>
/// <para>You might wonder why this is necessary. Two alternatives might come to
/// mind. First, you might imagine a system where generated extensions are
/// automatically registered when their containing classes are loaded. This
/// is a popular technique, but is bad design; among other things, it creates a
/// situation where behavior can change depending on what classes happen to be
/// loaded. It also introduces a security vulnerability, because an
/// unprivileged class could cause its code to be called unexpectedly from a
/// privileged class by registering itself as an extension of the right type.
/// </para>
/// <para>Another option you might consider is lazy parsing: do not parse an
/// extension until it is first requested, at which point the caller must
/// provide a type to use. This introduces a different set of problems. First,
/// it would require a mutex lock any time an extension was accessed, which
/// would be slow. Second, corrupt data would not be detected until first
/// access, at which point it would be much harder to deal with it. Third, it
/// could violate the expectation that message objects are immutable, since the
/// type provided could be any arbitrary message class. An unprivileged user
/// could take advantage of this to inject a mutable object into a message
/// belonging to privileged code and create mischief.</para>
/// </remarks>
public sealed class ExtensionRegistry {
private static readonly ExtensionRegistry empty = new ExtensionRegistry(
new Dictionary<string, ExtensionInfo>(),
new Dictionary<DescriptorIntPair, ExtensionInfo>(),
true);
private readonly IDictionary<string, ExtensionInfo> extensionsByName;
private readonly IDictionary<DescriptorIntPair, ExtensionInfo> extensionsByNumber;
private readonly bool readOnly;
private ExtensionRegistry(IDictionary<String, ExtensionInfo> extensionsByName,
IDictionary<DescriptorIntPair, ExtensionInfo> extensionsByNumber,
bool readOnly) {
this.extensionsByName = extensionsByName;
this.extensionsByNumber = extensionsByNumber;
this.readOnly = readOnly;
}
/// <summary>
/// Construct a new, empty instance.
/// </summary>
public static ExtensionRegistry CreateInstance() {
return new ExtensionRegistry(new Dictionary<string, ExtensionInfo>(),
new Dictionary<DescriptorIntPair, ExtensionInfo>(), false);
}
/// <summary>
/// Get the unmodifiable singleton empty instance.
/// </summary>
public static ExtensionRegistry Empty {
get { return empty; }
}
public ExtensionRegistry AsReadOnly() {
return new ExtensionRegistry(extensionsByName, extensionsByNumber, true);
}
/// <summary>
/// Finds an extension by fully-qualified field name, in the
/// proto namespace, i.e. result.Descriptor.FullName will match
/// <paramref name="fullName"/> if a match is found. A null
/// reference is returned if the extension can't be found.
/// </summary>
public ExtensionInfo this[string fullName] {
get {
ExtensionInfo ret;
extensionsByName.TryGetValue(fullName, out ret);
return ret;
}
}
/// <summary>
/// Finds an extension by containing type and field number.
/// A null reference is returned if the extension can't be found.
/// </summary>
public ExtensionInfo this[MessageDescriptor containingType, int fieldNumber] {
get {
ExtensionInfo ret;
extensionsByNumber.TryGetValue(new DescriptorIntPair(containingType, fieldNumber), out ret);
return ret;
}
}
/// <summary>
/// Add an extension from a generated file to the registry.
/// </summary>
public void Add<TExtension> (GeneratedExtensionBase<TExtension> extension) {
if (extension.Descriptor.MappedType == MappedType.Message) {
Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance));
} else {
Add(new ExtensionInfo(extension.Descriptor, null));
}
}
/// <summary>
/// Adds a non-message-type extension to the registry by descriptor.
/// </summary>
/// <param name="type"></param>
public void Add(FieldDescriptor type) {
if (type.MappedType == MappedType.Message) {
throw new ArgumentException("ExtensionRegistry.Add() must be provided a default instance "
+ "when adding an embedded message extension.");
}
Add(new ExtensionInfo(type, null));
}
/// <summary>
/// Adds a message-type-extension to the registry by descriptor.
/// </summary>
/// <param name="type"></param>
/// <param name="defaultInstance"></param>
public void Add(FieldDescriptor type, IMessage defaultInstance) {
if (type.MappedType != MappedType.Message) {
throw new ArgumentException("ExtensionRegistry.Add() provided a default instance for a "
+ "non-message extension.");
}
Add(new ExtensionInfo(type, defaultInstance));
}
private void Add(ExtensionInfo extension) {
if (readOnly) {
throw new InvalidOperationException("Cannot add entries to a read-only extension registry");
}
if (!extension.Descriptor.IsExtension) {
throw new ArgumentException("ExtensionRegistry.add() was given a FieldDescriptor for a "
+ "regular (non-extension) field.");
}
extensionsByName[extension.Descriptor.FullName] = extension;
extensionsByNumber[new DescriptorIntPair(extension.Descriptor.ContainingType,
extension.Descriptor.FieldNumber)] = extension;
FieldDescriptor field = extension.Descriptor;
if (field.ContainingType.Options.MessageSetWireFormat
&& field.FieldType == FieldType.Message
&& field.IsOptional
&& field.ExtensionScope == field.MessageType) {
// This is an extension of a MessageSet type defined within the extension
// type's own scope. For backwards-compatibility, allow it to be looked
// up by type name.
extensionsByName[field.MessageType.FullName] = extension;
}
}
/// <summary>
/// Nested type just used to represent a pair of MessageDescriptor and int, as
/// the key into the "by number" map.
/// </summary>
private struct DescriptorIntPair : IEquatable<DescriptorIntPair> {
readonly MessageDescriptor descriptor;
readonly int number;
internal DescriptorIntPair(MessageDescriptor descriptor, int number) {
this.descriptor = descriptor;
this.number = number;
}
public override int GetHashCode() {
return descriptor.GetHashCode() * ((1 << 16) - 1) + number;
}
public override bool Equals(object obj) {
if (!(obj is DescriptorIntPair)) {
return false;
}
return Equals((DescriptorIntPair)obj);
}
public bool Equals(DescriptorIntPair other) {
return descriptor == other.descriptor && number == other.number;
}
}
}
}
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers {
/// <summary>
/// Non-generic interface for all members whose signatures don't require knowledge of
/// the type being built. The generic interface extends this one. Some methods return
/// either an IBuilder or an IMessage; in these cases the generic interface redeclares
/// the same method with a type-specific signature. Implementations are encouraged to
/// use explicit interface implemenation for the non-generic form. This mirrors
/// how IEnumerable and IEnumerable&lt;T&gt; work.
/// </summary>
public interface IBuilder {
/// <summary>
/// Returns true iff all required fields in the message and all
/// embedded messages are set.
/// </summary>
bool IsInitialized { get; }
/// <summary>
/// Only present in the nongeneric interface - useful for tests, but
/// not as much in real life.
/// </summary>
IBuilder SetField(FieldDescriptor field, object value);
/// <summary>
/// Only present in the nongeneric interface - useful for tests, but
/// not as much in real life.
/// </summary>
IBuilder SetRepeatedField(FieldDescriptor field, int index, object value);
/// <summary>
/// Behaves like the equivalent property in IMessage&lt;T&gt;.
/// The returned map may or may not reflect future changes to the builder.
/// Either way, the returned map is unmodifiable.
/// </summary>
IDictionary<FieldDescriptor, object> AllFields { get; }
/// <summary>
/// Allows getting and setting of a field.
/// <see cref="IMessage{TMessage, TBuilder}.Item(FieldDescriptor)"/>
/// </summary>
/// <param name="field"></param>
/// <returns></returns>
object this[FieldDescriptor field] { get; set; }
/// <summary>
/// Get the message's type descriptor.
/// <see cref="IMessage{TMessage, TBuilder}.DescriptorForType"/>
/// </summary>
MessageDescriptor DescriptorForType { get; }
/// <summary>
/// <see cref="IMessage{TMessage, TBuilder}.GetRepeatedFieldCount"/>
/// </summary>
/// <param name="field"></param>
/// <returns></returns>
int GetRepeatedFieldCount(FieldDescriptor field);
/// <summary>
/// Allows getting and setting of a repeated field value.
/// <see cref="IMessage{TMessage, TBuilder}.Item(FieldDescriptor, int)"/>
/// </summary>
object this[FieldDescriptor field, int index] { get; set; }
/// <summary>
/// <see cref="IMessage{TMessage, TBuilder}.HasField"/>
/// </summary>
bool HasField(FieldDescriptor field);
/// <summary>
/// <see cref="IMessage{TMessage, TBuilder}.UnknownFields"/>
/// </summary>
UnknownFieldSet UnknownFields { get; set; }
/// <summary>
/// Create a builder for messages of the appropriate type for the given field.
/// Messages built with this can then be passed to the various mutation properties
/// and methods.
/// </summary>
IBuilder CreateBuilderForField(FieldDescriptor field);
#region Methods which are like those of the generic form, but without any knowledge of the type parameters
IBuilder WeakAddRepeatedField(FieldDescriptor field, object value);
IBuilder WeakClear();
IBuilder WeakClearField(FieldDescriptor field);
IBuilder WeakMergeFrom(IMessage message);
IBuilder WeakMergeFrom(ByteString data);
IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry);
IBuilder WeakMergeFrom(CodedInputStream input);
IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry);
IMessage WeakBuild();
IMessage WeakBuildPartial();
IBuilder WeakClone();
IMessage WeakDefaultInstanceForType { get; }
#endregion
}
/// <summary>
/// Interface implemented by Protocol Message builders.
/// TODO(jonskeet): Consider "SetXXX" methods returning the builder, as well as the properties.
/// </summary>
/// <typeparam name="TMessage">Type of message</typeparam>
/// <typeparam name="TBuilder">Type of builder</typeparam>
public interface IBuilder<TMessage, TBuilder> : IBuilder
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder> {
TBuilder SetUnknownFields(UnknownFieldSet unknownFields);
/// <summary>
/// Resets all fields to their default values.
/// </summary>
TBuilder Clear();
/// <summary>
/// Merge the specified other message into the message being
/// built. Merging occurs as follows. For each field:
/// For singular primitive fields, if the field is set in <paramref name="other"/>,
/// then <paramref name="other"/>'s value overwrites the value in this message.
/// For singular message fields, if the field is set in <paramref name="other"/>,
/// it is merged into the corresponding sub-message of this message using the same
/// merging rules.
/// For repeated fields, the elements in <paramref name="other"/> are concatenated
/// with the elements in this message.
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
TBuilder MergeFrom(TMessage other);
/// <summary>
/// Merge the specified other message which may be a different implementation of
/// the same message descriptor.
/// </summary>
TBuilder MergeFrom(IMessage other);
/// <summary>
/// Constructs the final message. Once this is called, this Builder instance
/// is no longer valid, and calling any other method may throw a
/// NullReferenceException. If you need to continue working with the builder
/// after calling Build, call Clone first.
/// </summary>
/// <exception cref="UninitializedMessageException">the message
/// is missing one or more required fields; use BuildPartial to bypass
/// this check</exception>
TMessage Build();
/// <summary>
/// Like Build(), but does not throw an exception if the message is missing
/// required fields. Instead, a partial message is returned.
/// </summary>
TMessage BuildPartial();
/// <summary>
/// Clones this builder.
/// TODO(jonskeet): Explain depth of clone.
/// </summary>
TBuilder Clone();
/// <summary>
/// Parses a message of this type from the input and merges it with this
/// message, as if using MergeFrom(IMessage&lt;T&gt;).
/// </summary>
/// <remarks>
/// Warning: This does not verify that all required fields are present
/// in the input message. If you call Build() without setting all
/// required fields, it will throw an UninitializedMessageException.
/// There are a few good ways to deal with this:
/// <list>
/// <item>Call IsInitialized to verify to verify that all required fields are
/// set before building.</item>
/// <item>Parse the message separately using one of the static ParseFrom
/// methods, then use MergeFrom(IMessage&lt;T&gt;) to merge it with
/// this one. ParseFrom will throw an InvalidProtocolBufferException
/// (an IOException) if some required fields are missing.
/// Use BuildPartial to build, which ignores missing required fields.
/// </list>
/// </remarks>
TBuilder MergeFrom(CodedInputStream input);
/// <summary>
/// Like MergeFrom(CodedInputStream), but also parses extensions.
/// The extensions that you want to be able to parse must be registered
/// in <paramref name="extensionRegistry"/>. Extensions not in the registry
/// will be treated as unknown fields.
/// </summary>
TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry);
/// <summary>
/// Get's the message's type's default instance.
/// <see cref="IMessage{TMessage}.DefaultInstanceForType" />
/// </summary>
TMessage DefaultInstanceForType { get; }
/// <summary>
/// Clears the field. This is exactly equivalent to calling the generated
/// Clear method corresponding to the field.
/// </summary>
/// <param name="field"></param>
/// <returns></returns>
TBuilder ClearField(FieldDescriptor field);
/// <summary>
/// Appends the given value as a new element for the specified repeated field.
/// </summary>
/// <exception cref="ArgumentException">the field is not a repeated field,
/// the field does not belong to this builder's type, or the value is
/// of the incorrect type
/// </exception>
TBuilder AddRepeatedField(FieldDescriptor field, object value);
/// <summary>
/// Merge some unknown fields into the set for this message.
/// </summary>
TBuilder MergeUnknownFields(UnknownFieldSet unknownFields);
/// <summary>
/// Like MergeFrom(Stream), but does not read until the end of the file.
/// Instead, the size of the message (encoded as a varint) is read first,
/// then the message data. Use Message.WriteDelimitedTo(Stream) to
/// write messages in this format.
/// </summary>
/// <param name="input"></param>
TBuilder MergeDelimitedFrom(Stream input);
/// <summary>
/// Like MergeDelimitedFrom(Stream) but supporting extensions.
/// </summary>
TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry);
#region Convenience methods
/// <summary>
/// Parse <paramref name="data"/> as a message of this type and merge
/// it with the message being built. This is just a small wrapper around
/// MergeFrom(CodedInputStream).
/// </summary>
TBuilder MergeFrom(ByteString data);
/// <summary>
/// Parse <paramref name="data"/> as a message of this type and merge
/// it with the message being built. This is just a small wrapper around
/// MergeFrom(CodedInputStream, ExtensionRegistry).
/// </summary>
TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry);
/// <summary>
/// Parse <paramref name="data"/> as a message of this type and merge
/// it with the message being built. This is just a small wrapper around
/// MergeFrom(CodedInputStream).
/// </summary>
TBuilder MergeFrom(byte[] data);
/// <summary>
/// Parse <paramref name="data"/> as a message of this type and merge
/// it with the message being built. This is just a small wrapper around
/// MergeFrom(CodedInputStream, ExtensionRegistry).
/// </summary>
TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry);
/// <summary>
/// Parse <paramref name="input"/> as a message of this type and merge
/// it with the message being built. This is just a small wrapper around
/// MergeFrom(CodedInputStream). Note that this method always reads
/// the entire input (unless it throws an exception). If you want it to
/// stop earlier, you will need to wrap the input in a wrapper
/// stream which limits reading. Or, use IMessage.WriteDelimitedTo(Stream)
/// to write your message and MmergeDelimitedFrom(Stream) to read it.
/// Despite usually reading the entire stream, this method never closes the stream.
/// </summary>
TBuilder MergeFrom(Stream input);
/// <summary>
/// Parse <paramref name="input"/> as a message of this type and merge
/// it with the message being built. This is just a small wrapper around
/// MergeFrom(CodedInputStream, ExtensionRegistry).
/// </summary>
TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry);
#endregion
}
}
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers {
/// <summary>
/// Non-generic interface used for all parts of the API which don't require
/// any type knowledge.
/// </summary>
public interface IMessage {
/// <summary>
/// Returns the message's type's descriptor. This differs from the
/// Descriptor property of each generated message class in that this
/// method is an abstract method of IMessage whereas Descriptor is
/// a static property of a specific class. They return the same thing.
/// </summary>
MessageDescriptor DescriptorForType { get; }
/// <summary>
/// Returns a collection of all the fields in this message which are set
/// and their corresponding values. A singular ("required" or "optional")
/// field is set iff HasField() returns true for that field. A "repeated"
/// field is set iff GetRepeatedFieldSize() is greater than zero. The
/// values are exactly what would be returned by calling
/// GetField(FieldDescriptor) for each field. The map
/// is guaranteed to be a sorted map, so iterating over it will return fields
/// in order by field number.
/// </summary>
IDictionary<FieldDescriptor, object> AllFields { get; }
/// <summary>
/// Returns true if the given field is set. This is exactly equivalent
/// to calling the generated "Has" property corresponding to the field.
/// </summary>
/// <exception cref="ArgumentException">the field is a repeated field,
/// or it's not a field of this type</exception>
bool HasField(FieldDescriptor field);
/// <summary>
/// Obtains the value of the given field, or the default value if
/// it isn't set. For value type fields, the boxed value is returned.
/// For enum fields, the EnumValueDescriptor for the enum is returned.
/// For embedded message fields, the sub-message
/// is returned. For repeated fields, an IList&lt;T&gt; is returned.
/// </summary>
object this[FieldDescriptor field] { get; }
/// <summary>
/// Returns the number of elements of a repeated field. This is
/// exactly equivalent to calling the generated "Count" property
/// corresponding to the field.
/// </summary>
/// <exception cref="ArgumentException">the field is not a repeated field,
/// or it's not a field of this type</exception>
int GetRepeatedFieldCount(FieldDescriptor field);
/// <summary>
/// Gets an element of a repeated field. For value type fields
/// excluding enums, the boxed value is returned. For embedded
/// message fields, the sub-message is returned. For enums, the
/// relevant EnumValueDescriptor is returned.
/// </summary>
/// <exception cref="ArgumentException">the field is not a repeated field,
/// or it's not a field of this type</exception>
/// <exception cref="ArgumentOutOfRangeException">the index is out of
/// range for the repeated field's value</exception>
object this[FieldDescriptor field, int index] { get; }
/// <summary>
/// Returns the unknown fields for this message.
/// </summary>
UnknownFieldSet UnknownFields { get; }
/// <summary>
/// Returns true iff all required fields in the message and all embedded
/// messages are set.
/// </summary>
bool IsInitialized { get; }
/// <summary>
/// Serializes the message and writes it to the given output stream.
/// This does not flush or close the stream.
/// </summary>
/// <remarks>
/// Protocol Buffers are not self-delimiting. Therefore, if you write
/// any more data to the stream after the message, you must somehow ensure
/// that the parser on the receiving end does not interpret this as being
/// part of the protocol message. One way of doing this is by writing the size
/// of the message before the data, then making sure you limit the input to
/// that size when receiving the data. Alternatively, use WriteDelimitedTo(Stream).
/// </remarks>
void WriteTo(CodedOutputStream output);
/// <summary>
/// Like WriteTo(Stream) but writes the size of the message as a varint before
/// writing the data. This allows more data to be written to the stream after the
/// message without the need to delimit the message data yourself. Use
/// IBuilder.MergeDelimitedFrom(Stream) or the static method
/// YourMessageType.ParseDelimitedFrom(Stream) to parse messages written by this method.
/// </summary>
/// <param name="output"></param>
void WriteDelimitedTo(Stream output);
/// <summary>
/// Returns the number of bytes required to encode this message.
/// The result is only computed on the first call and memoized after that.
/// </summary>
int SerializedSize { get; }
#region Comparison and hashing
/// <summary>
/// Compares the specified object with this message for equality.
/// Returns true iff the given object is a message of the same type
/// (as defined by DescriptorForType) and has identical values
/// for all its fields.
/// </summary>
bool Equals(object other);
/// <summary>
/// Returns the hash code value for this message.
/// TODO(jonskeet): Specify the hash algorithm, but better than the Java one!
/// </summary>
int GetHashCode();
#endregion
#region Convenience methods
/// <summary>
/// Converts the message to a string in protocol buffer text format.
/// This is just a trivial wrapper around TextFormat.PrintToString.
/// </summary>
string ToString();
/// <summary>
/// Serializes the message to a ByteString. This is a trivial wrapper
/// around WriteTo(CodedOutputStream).
/// </summary>
ByteString ToByteString();
/// <summary>
/// Serializes the message to a byte array. This is a trivial wrapper
/// around WriteTo(CodedOutputStream).
/// </summary>
byte[] ToByteArray();
/// <summary>
/// Serializes the message and writes it to the given stream.
/// This is just a wrapper around WriteTo(CodedOutputStream). This
/// does not flush or close the stream.
/// </summary>
/// <param name="output"></param>
void WriteTo(Stream output);
#endregion
/// <summary>
/// Creates a builder for the type, but in a weakly typed manner. This
/// is typically implemented by strongly typed messages by just returning
/// the result of CreateBuilderForType.
/// </summary>
IBuilder WeakCreateBuilderForType();
/// <summary>
/// Creates a builder with the same contents as this message. This
/// is typically implemented by strongly typed messages by just returning
/// the result of ToBuilder.
/// </summary>
IBuilder WeakToBuilder();
IMessage WeakDefaultInstanceForType { get; }
}
public interface IMessage<TMessage> : IMessage {
/// <summary>
/// Returns an instance of this message type with all fields set to
/// their default values. This may or may not be a singleton. This differs
/// from the DefaultInstance property of each generated message class in that this
/// method is an abstract method of IMessage whereas DefaultInstance is
/// a static property of a specific class. They return the same thing.
/// </summary>
TMessage DefaultInstanceForType { get; }
}
/// <summary>
/// Type-safe interface for all generated messages to implement.
/// </summary>
public interface IMessage<TMessage, TBuilder> : IMessage<TMessage>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder> {
#region Builders
/// <summary>
/// Constructs a new builder for a message of the same type as this message.
/// </summary>
TBuilder CreateBuilderForType();
/// <summary>
/// Creates a builder with the same contents as this current instance.
/// This is typically implemented by strongly typed messages by just
/// returning the result of ToBuilder().
/// </summary>
TBuilder ToBuilder();
#endregion
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment