#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 { /// /// 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<T> work. /// public interface IBuilder : IBuilderLite { /// /// Returns true iff all required fields in the message and all /// embedded messages are set. /// new bool IsInitialized { get; } /// /// Only present in the nongeneric interface - useful for tests, but /// not as much in real life. /// IBuilder SetField(FieldDescriptor field, object value); /// /// Only present in the nongeneric interface - useful for tests, but /// not as much in real life. /// IBuilder SetRepeatedField(FieldDescriptor field, int index, object value); /// /// Behaves like the equivalent property in IMessage<T>. /// The returned map may or may not reflect future changes to the builder. /// Either way, the returned map is unmodifiable. /// IDictionary AllFields { get; } /// /// Allows getting and setting of a field. /// /// /// /// object this[FieldDescriptor field] { get; set; } /// /// Get the message's type descriptor. /// /// MessageDescriptor DescriptorForType { get; } /// /// /// /// /// int GetRepeatedFieldCount(FieldDescriptor field); /// /// Allows getting and setting of a repeated field value. /// /// object this[FieldDescriptor field, int index] { get; set; } /// /// /// bool HasField(FieldDescriptor field); /// /// /// UnknownFieldSet UnknownFields { get; set; } /// /// 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. /// 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); new IBuilder WeakClear(); IBuilder WeakClearField(FieldDescriptor field); IBuilder WeakMergeFrom(IMessage message); new IBuilder WeakMergeFrom(ByteString data); new IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry); new IBuilder WeakMergeFrom(ICodedInputStream input); new IBuilder WeakMergeFrom(ICodedInputStream input, ExtensionRegistry registry); new IMessage WeakBuild(); new IMessage WeakBuildPartial(); new IBuilder WeakClone(); new IMessage WeakDefaultInstanceForType { get; } #endregion } /// /// Interface implemented by Protocol Message builders. /// TODO(jonskeet): Consider "SetXXX" methods returning the builder, as well as the properties. /// /// Type of message /// Type of builder public interface IBuilder : IBuilder, IBuilderLite where TMessage : IMessage where TBuilder : IBuilder { TBuilder SetUnknownFields(UnknownFieldSet unknownFields); /// /// Resets all fields to their default values. /// new TBuilder Clear(); /// /// Merge the specified other message which may be a different implementation of /// the same message descriptor. /// TBuilder MergeFrom(IMessage other); /// /// 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. /// /// the message /// is missing one or more required fields; use BuildPartial to bypass /// this check new TMessage Build(); /// /// Like Build(), but does not throw an exception if the message is missing /// required fields. Instead, a partial message is returned. /// new TMessage BuildPartial(); /// /// Clones this builder. /// TODO(jonskeet): Explain depth of clone. /// new TBuilder Clone(); /// /// Parses a message of this type from the input and merges it with this /// message, as if using MergeFrom(IMessage<T>). /// /// /// 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: /// /// Call IsInitialized to verify to verify that all required fields are /// set before building. /// Parse the message separately using one of the static ParseFrom /// methods, then use MergeFrom(IMessage<T>) 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. /// /// new TBuilder MergeFrom(ICodedInputStream input); /// /// Like MergeFrom(ICodedInputStream), but also parses extensions. /// The extensions that you want to be able to parse must be registered /// in . Extensions not in the registry /// will be treated as unknown fields. /// new TBuilder MergeFrom(ICodedInputStream input, ExtensionRegistry extensionRegistry); /// /// Get's the message's type's default instance. /// /// new TMessage DefaultInstanceForType { get; } /// /// Clears the field. This is exactly equivalent to calling the generated /// Clear method corresponding to the field. /// /// /// TBuilder ClearField(FieldDescriptor field); /// /// Appends the given value as a new element for the specified repeated field. /// /// 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 /// TBuilder AddRepeatedField(FieldDescriptor field, object value); /// /// Merge some unknown fields into the set for this message. /// TBuilder MergeUnknownFields(UnknownFieldSet unknownFields); /// /// 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. /// /// new TBuilder MergeDelimitedFrom(Stream input); /// /// Like MergeDelimitedFrom(Stream) but supporting extensions. /// new TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry); #region Convenience methods /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around /// MergeFrom(ICodedInputStream). /// new TBuilder MergeFrom(ByteString data); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around /// MergeFrom(ICodedInputStream, extensionRegistry). /// new TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around /// MergeFrom(ICodedInputStream). /// new TBuilder MergeFrom(byte[] data); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around /// MergeFrom(ICodedInputStream, extensionRegistry). /// new TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around /// MergeFrom(ICodedInputStream). 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. /// new TBuilder MergeFrom(Stream input); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around /// MergeFrom(ICodedInputStream, extensionRegistry). /// new TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry); #endregion } }