Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
c07571a7
Commit
c07571a7
authored
Nov 04, 2010
by
csharptest
Committed by
unknown
Nov 04, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added copy of existing classes that will be made Lite
parent
57599ef1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
798 additions
and
0 deletions
+798
-0
ExtensionRegistryLite.cs
src/ProtocolBuffers/ExtensionRegistryLite.cs
+245
-0
IBuilderLite.cs
src/ProtocolBuffers/IBuilderLite.cs
+317
-0
IMessageLite.cs
src/ProtocolBuffers/IMessageLite.cs
+236
-0
No files found.
src/ProtocolBuffers/ExtensionRegistryLite.cs
0 → 100644
View file @
c07571a7
#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
;
}
}
}
}
src/ProtocolBuffers/IBuilderLite.cs
0 → 100644
View file @
c07571a7
#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<T> 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<T>.
/// 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<T>).
/// </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<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.
/// </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
}
}
src/ProtocolBuffers/IMessageLite.cs
0 → 100644
View file @
c07571a7
#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<T> 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
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment