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
09809820
Commit
09809820
authored
Aug 14, 2008
by
Jon Skeet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Evil reflection optimisation.
parent
38da52d3
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
199 additions
and
51 deletions
+199
-51
Delegates.cs
csharp/ProtocolBuffers/FieldAccess/Delegates.cs
+20
-3
IFieldAccessor.cs
csharp/ProtocolBuffers/FieldAccess/IFieldAccessor.cs
+4
-4
ReflectionUtil.cs
csharp/ProtocolBuffers/FieldAccess/ReflectionUtil.cs
+118
-0
RepeatedEnumAccessor.cs
csharp/ProtocolBuffers/FieldAccess/RepeatedEnumAccessor.cs
+3
-3
RepeatedMessageAccessor.cs
...rp/ProtocolBuffers/FieldAccess/RepeatedMessageAccessor.cs
+6
-5
RepeatedPrimitiveAccessor.cs
.../ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs
+22
-15
SingleMessageAccessor.cs
csharp/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs
+6
-6
SinglePrimitiveAccessor.cs
...rp/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs
+15
-11
GeneratedBuilder.cs
csharp/ProtocolBuffers/GeneratedBuilder.cs
+3
-3
GeneratedMessage.cs
csharp/ProtocolBuffers/GeneratedMessage.cs
+1
-1
ProtocolBuffers.csproj
csharp/ProtocolBuffers/ProtocolBuffers.csproj
+1
-0
No files found.
csharp/ProtocolBuffers/FieldAccess/Delegates.cs
View file @
09809820
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.
// http://code.google.com/p/protobuf/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace
Google.ProtocolBuffers.FieldAccess
{
// TODO(jonskeet): Convert these to Func/Action family
delegate
bool
HasDelegate
<
T
>(
T
message
);
delegate
T
ClearDelegate
<
T
>(
T
builder
);
delegate
int
RepeatedCountDelegate
<
T
>(
T
message
);
delegate
object
GetValueDelegate
<
T
>(
T
message
);
delegate
void
SingleValueDelegate
<
TSource
>(
TSource
source
,
object
value
);
delegate
IBuilder
CreateBuilderDelegate
();
delegate
object
GetIndexedValueDelegate
<
T
>(
T
message
,
int
index
);
delegate
object
SetIndexedValueDelegate
<
T
>(
T
message
,
int
index
,
object
value
);
}
csharp/ProtocolBuffers/FieldAccess/IFieldAccessor.cs
View file @
09809820
...
...
@@ -58,18 +58,18 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// <summary>
/// Accessor for repeated fields
/// </summary>
object
GetRepeatedValue
(
I
Message
message
,
int
index
);
object
GetRepeatedValue
(
T
Message
message
,
int
index
);
/// <summary>
/// Mutator for repeated fields
/// </summary>
void
SetRepeated
(
I
Builder
builder
,
int
index
,
object
value
);
void
SetRepeated
(
T
Builder
builder
,
int
index
,
object
value
);
/// <summary>
/// Adds the specified value to the field in the given builder.
/// </summary>
void
AddRepeated
(
I
Builder
builder
,
object
value
);
void
AddRepeated
(
T
Builder
builder
,
object
value
);
/// <summary>
/// Returns a read-only wrapper around the value of a repeated field.
/// </summary>
object
GetRepeatedWrapper
(
I
Builder
builder
);
object
GetRepeatedWrapper
(
T
Builder
builder
);
}
}
csharp/ProtocolBuffers/FieldAccess/ReflectionUtil.cs
0 → 100644
View file @
09809820
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.
// http://code.google.com/p/protobuf/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using
System
;
using
System.Reflection
;
namespace
Google.ProtocolBuffers.FieldAccess
{
/// <summary>
/// The methods in this class are somewhat evil, and should not be tampered with lightly.
/// Basically they allow the creation of relatively weakly typed delegates from MethodInfos
/// which are more strongly typed. They do this by creating an appropriate strongly typed
/// delegate from the MethodInfo, and then calling that within an anonymous method.
/// Mind-bending stuff (at least to your humble narrator) but the resulting delegates are
/// very fast compared with calling Invoke later on.
/// </summary>
internal
static
class
ReflectionUtil
{
/// <summary>
/// Creates a delegate which will execute the given method and then return
/// the result as an object.
/// </summary>
public
static
GetValueDelegate
<
T
>
CreateUpcastDelegate
<
T
>(
MethodInfo
method
)
{
// The tricky bit is invoking CreateCreateUpcastDelegateImpl with the right type parameters
MethodInfo
openImpl
=
typeof
(
ReflectionUtil
).
GetMethod
(
"CreateUpcastDelegateImpl"
);
MethodInfo
closedImpl
=
openImpl
.
MakeGenericMethod
(
typeof
(
T
),
method
.
ReturnType
);
return
(
GetValueDelegate
<
T
>)
closedImpl
.
Invoke
(
null
,
new
object
[]
{
method
});
}
delegate
TResult
Getter
<
TSource
,
TResult
>(
TSource
source
);
/// <summary>
/// Method used solely for implementing CreateUpcastDelegate. Public to avoid trust issues
/// in low-trust scenarios, e.g. Silverlight.
/// TODO(jonskeet): Check any of this actually works in Silverlight...
/// </summary>
public
static
GetValueDelegate
<
TSource
>
CreateUpcastDelegateImpl
<
TSource
,
TResult
>(
MethodInfo
method
)
{
// Convert the reflection call into an open delegate, i.e. instead of calling x.Method()
// we'll call getter(x).
Getter
<
TSource
,
TResult
>
getter
=
(
Getter
<
TSource
,
TResult
>)
Delegate
.
CreateDelegate
(
typeof
(
Getter
<
TSource
,
TResult
>),
method
);
// Implicit upcast to object (within the delegate)
return
delegate
(
TSource
source
)
{
return
getter
(
source
);
};
}
/// <summary>
/// Creates a delegate which will execute the given method after casting the parameter
/// down from object to the required parameter type.
/// </summary>
public
static
SingleValueDelegate
<
T
>
CreateDowncastDelegate
<
T
>(
MethodInfo
method
)
{
MethodInfo
openImpl
=
typeof
(
ReflectionUtil
).
GetMethod
(
"CreateDowncastDelegateImpl"
);
MethodInfo
closedImpl
=
openImpl
.
MakeGenericMethod
(
typeof
(
T
),
method
.
GetParameters
()[
0
].
ParameterType
);
return
(
SingleValueDelegate
<
T
>)
closedImpl
.
Invoke
(
null
,
new
object
[]
{
method
});
}
delegate
void
OpenSingleValueDelegate
<
TSource
,
TParam
>(
TSource
source
,
TParam
parameter
);
public
static
SingleValueDelegate
<
TSource
>
CreateDowncastDelegateImpl
<
TSource
,
TParam
>(
MethodInfo
method
)
{
// Convert the reflection call into an open delegate, i.e. instead of calling x.Method(y) we'll
// call Method(x, y)
OpenSingleValueDelegate
<
TSource
,
TParam
>
call
=
(
OpenSingleValueDelegate
<
TSource
,
TParam
>)
Delegate
.
CreateDelegate
(
typeof
(
OpenSingleValueDelegate
<
TSource
,
TParam
>),
method
);
return
delegate
(
TSource
source
,
object
parameter
)
{
call
(
source
,
(
TParam
)
parameter
);
};
}
/// <summary>
/// Creates a delegate which will execute the given method after casting the parameter
/// down from object to the required parameter type.
/// </summary>
public
static
SingleValueDelegate
<
T
>
CreateDowncastDelegateIgnoringReturn
<
T
>(
MethodInfo
method
)
{
MethodInfo
openImpl
=
typeof
(
ReflectionUtil
).
GetMethod
(
"CreateDowncastDelegateIgnoringReturnImpl"
);
MethodInfo
closedImpl
=
openImpl
.
MakeGenericMethod
(
typeof
(
T
),
method
.
GetParameters
()[
0
].
ParameterType
,
method
.
ReturnType
);
return
(
SingleValueDelegate
<
T
>)
closedImpl
.
Invoke
(
null
,
new
object
[]
{
method
});
}
delegate
TReturn
OpenSingleValueDelegate
<
TSource
,
TParam
,
TReturn
>(
TSource
source
,
TParam
parameter
);
public
static
SingleValueDelegate
<
TSource
>
CreateDowncastDelegateIgnoringReturnImpl
<
TSource
,
TParam
,
TReturn
>(
MethodInfo
method
)
{
// Convert the reflection call into an open delegate, i.e. instead of calling x.Method(y) we'll
// call Method(x, y)
OpenSingleValueDelegate
<
TSource
,
TParam
,
TReturn
>
call
=
(
OpenSingleValueDelegate
<
TSource
,
TParam
,
TReturn
>)
Delegate
.
CreateDelegate
(
typeof
(
OpenSingleValueDelegate
<
TSource
,
TParam
,
TReturn
>),
method
);
return
delegate
(
TSource
source
,
object
parameter
)
{
call
(
source
,
(
TParam
)
parameter
);
};
}
delegate
T
OpenCreateBuilderDelegate
<
T
>();
/// <summary>
/// Creates a delegate which will execute the given static method and cast the result up to IBuilder.
/// </summary>
public
static
CreateBuilderDelegate
CreateStaticUpcastDelegate
(
MethodInfo
method
)
{
MethodInfo
openImpl
=
typeof
(
ReflectionUtil
).
GetMethod
(
"CreateStaticUpcastDelegateImpl"
);
MethodInfo
closedImpl
=
openImpl
.
MakeGenericMethod
(
method
.
ReturnType
);
return
(
CreateBuilderDelegate
)
closedImpl
.
Invoke
(
null
,
new
object
[]
{
method
});
}
public
static
CreateBuilderDelegate
CreateStaticUpcastDelegateImpl
<
T
>(
MethodInfo
method
)
{
OpenCreateBuilderDelegate
<
T
>
call
=
(
OpenCreateBuilderDelegate
<
T
>)
Delegate
.
CreateDelegate
(
typeof
(
OpenCreateBuilderDelegate
<
T
>),
method
);
return
delegate
{
return
(
IBuilder
)
call
();
};
}
}
}
csharp/ProtocolBuffers/FieldAccess/RepeatedEnumAccessor.cs
View file @
09809820
...
...
@@ -42,18 +42,18 @@ namespace Google.ProtocolBuffers.FieldAccess {
return
Lists
.
AsReadOnly
(
ret
);
}
public
override
object
GetRepeatedValue
(
I
Message
message
,
int
index
)
{
public
override
object
GetRepeatedValue
(
T
Message
message
,
int
index
)
{
// Note: This relies on the fact that the CLR allows unboxing from an enum to
// its underlying value
int
rawValue
=
(
int
)
base
.
GetRepeatedValue
(
message
,
index
);
return
enumDescriptor
.
FindValueByNumber
(
rawValue
);
}
public
override
void
AddRepeated
(
I
Builder
builder
,
object
value
)
{
public
override
void
AddRepeated
(
T
Builder
builder
,
object
value
)
{
base
.
AddRepeated
(
builder
,
((
EnumValueDescriptor
)
value
).
Number
);
}
public
override
void
SetRepeated
(
I
Builder
builder
,
int
index
,
object
value
)
{
public
override
void
SetRepeated
(
T
Builder
builder
,
int
index
,
object
value
)
{
base
.
SetRepeated
(
builder
,
index
,
((
EnumValueDescriptor
)
value
).
Number
);
}
}
...
...
csharp/ProtocolBuffers/FieldAccess/RepeatedMessageAccessor.cs
View file @
09809820
...
...
@@ -33,13 +33,14 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// in a message type "Foo", a field called "bar" might be of type "Baz". This
/// method is Baz.CreateBuilder.
/// </summary>
private
readonly
MethodInfo
createBuilderMethod
;
private
readonly
CreateBuilderDelegate
createBuilderDelegate
;
internal
RepeatedMessageAccessor
(
string
name
)
:
base
(
name
)
{
createBuilderMethod
=
ClrType
.
GetMethod
(
"CreateBuilder"
,
new
Type
[
0
]);
MethodInfo
createBuilderMethod
=
ClrType
.
GetMethod
(
"CreateBuilder"
,
new
Type
[
0
]);
if
(
createBuilderMethod
==
null
)
{
throw
new
ArgumentException
(
"No public static CreateBuilder method declared in "
+
ClrType
.
Name
);
}
createBuilderDelegate
=
ReflectionUtil
.
CreateStaticUpcastDelegate
(
createBuilderMethod
);
}
/// <summary>
...
...
@@ -58,15 +59,15 @@ namespace Google.ProtocolBuffers.FieldAccess {
return
CreateBuilder
().
WeakMergeFrom
(
message
).
WeakBuild
();
}
public
override
void
SetRepeated
(
I
Builder
builder
,
int
index
,
object
value
)
{
public
override
void
SetRepeated
(
T
Builder
builder
,
int
index
,
object
value
)
{
base
.
SetRepeated
(
builder
,
index
,
CoerceType
(
value
));
}
public
override
IBuilder
CreateBuilder
()
{
return
(
IBuilder
)
createBuilderMethod
.
Invoke
(
null
,
null
);
return
createBuilderDelegate
(
);
}
public
override
void
AddRepeated
(
I
Builder
builder
,
object
value
)
{
public
override
void
AddRepeated
(
T
Builder
builder
,
object
value
)
{
base
.
AddRepeated
(
builder
,
CoerceType
(
value
));
}
}
...
...
csharp/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs
View file @
09809820
...
...
@@ -25,13 +25,15 @@ namespace Google.ProtocolBuffers.FieldAccess {
where
TMessage
:
IMessage
<
TMessage
,
TBuilder
>
where
TBuilder
:
IBuilder
<
TMessage
,
TBuilder
>
{
private
readonly
PropertyInfo
messageProperty
;
private
readonly
PropertyInfo
builderProperty
;
private
readonly
RepeatedCountDelegate
<
TMessage
>
countDelegate
;
private
readonly
Type
clrType
;
private
readonly
GetValueDelegate
<
TMessage
>
getValueDelegate
;
private
readonly
ClearDelegate
<
TBuilder
>
clearDelegate
;
private
readonly
MethodInfo
addMethod
;
private
readonly
SingleValueDelegate
<
TBuilder
>
addValueDelegate
;
private
readonly
GetValueDelegate
<
TBuilder
>
getRepeatedWrapperDelegate
;
private
readonly
RepeatedCountDelegate
<
TMessage
>
countDelegate
;
private
readonly
MethodInfo
getElementMethod
;
private
readonly
MethodInfo
setElementMethod
;
/// <summary>
/// The CLR type of the field (int, the enum type, ByteString, the message etc).
...
...
@@ -39,16 +41,17 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// value.
/// </summary>
protected
Type
ClrType
{
get
{
return
getElementMethod
.
Return
Type
;
}
get
{
return
clr
Type
;
}
}
internal
RepeatedPrimitiveAccessor
(
string
name
)
{
messageProperty
=
typeof
(
TMessage
).
GetProperty
(
name
+
"List"
);
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
name
+
"List"
);
PropertyInfo
messageProperty
=
typeof
(
TMessage
).
GetProperty
(
name
+
"List"
);
PropertyInfo
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
name
+
"List"
);
PropertyInfo
countProperty
=
typeof
(
TMessage
).
GetProperty
(
name
+
"Count"
);
MethodInfo
clearMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Clear"
+
name
);
getElementMethod
=
typeof
(
TMessage
).
GetMethod
(
"Get"
+
name
,
new
Type
[]
{
typeof
(
int
)
});
addMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Add"
+
name
,
new
Type
[]
{
ClrType
});
clrType
=
getElementMethod
.
ReturnType
;
MethodInfo
addMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Add"
+
name
,
new
Type
[]
{
ClrType
});
setElementMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Set"
+
name
,
new
Type
[]
{
typeof
(
int
),
ClrType
});
if
(
messageProperty
==
null
||
builderProperty
==
null
...
...
@@ -62,6 +65,9 @@ namespace Google.ProtocolBuffers.FieldAccess {
clearDelegate
=
(
ClearDelegate
<
TBuilder
>)
Delegate
.
CreateDelegate
(
typeof
(
ClearDelegate
<
TBuilder
>),
clearMethod
);
countDelegate
=
(
RepeatedCountDelegate
<
TMessage
>)
Delegate
.
CreateDelegate
(
typeof
(
RepeatedCountDelegate
<
TMessage
>),
countProperty
.
GetGetMethod
());
getValueDelegate
=
ReflectionUtil
.
CreateUpcastDelegate
<
TMessage
>(
messageProperty
.
GetGetMethod
());
addValueDelegate
=
ReflectionUtil
.
CreateDowncastDelegateIgnoringReturn
<
TBuilder
>(
addMethod
);
getRepeatedWrapperDelegate
=
ReflectionUtil
.
CreateUpcastDelegate
<
TBuilder
>(
builderProperty
.
GetGetMethod
());
}
public
bool
Has
(
TMessage
message
)
{
...
...
@@ -73,7 +79,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
}
public
virtual
object
GetValue
(
TMessage
message
)
{
return
messageProperty
.
GetValue
(
message
,
null
);
return
getValueDelegate
(
message
);
}
public
void
SetValue
(
TBuilder
builder
,
object
value
)
{
...
...
@@ -95,24 +101,24 @@ namespace Google.ProtocolBuffers.FieldAccess {
return
countDelegate
(
message
);
}
public
virtual
object
GetRepeatedValue
(
I
Message
message
,
int
index
)
{
public
virtual
object
GetRepeatedValue
(
T
Message
message
,
int
index
)
{
return
getElementMethod
.
Invoke
(
message
,
new
object
[]
{
index
}
);
}
public
virtual
void
SetRepeated
(
I
Builder
builder
,
int
index
,
object
value
)
{
public
virtual
void
SetRepeated
(
T
Builder
builder
,
int
index
,
object
value
)
{
setElementMethod
.
Invoke
(
builder
,
new
object
[]
{
index
,
value
}
);
}
public
virtual
void
AddRepeated
(
I
Builder
builder
,
object
value
)
{
add
Method
.
Invoke
(
builder
,
new
object
[]
{
value
}
);
public
virtual
void
AddRepeated
(
T
Builder
builder
,
object
value
)
{
add
ValueDelegate
(
builder
,
value
);
}
/// <summary>
/// The builder class's accessor already builds a read-only wrapper for
/// us, which is exactly what we want.
/// </summary>
public
object
GetRepeatedWrapper
(
I
Builder
builder
)
{
return
builderProperty
.
GetValue
(
builder
,
null
);
public
object
GetRepeatedWrapper
(
T
Builder
builder
)
{
return
getRepeatedWrapperDelegate
(
builder
);
}
}
}
\ No newline at end of file
csharp/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs
View file @
09809820
...
...
@@ -29,15 +29,14 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// in a message type "Foo", a field called "bar" might be of type "Baz". This
/// method is Baz.CreateBuilder.
/// </summary>
private
readonly
MethodInfo
createBuilderMethod
;
private
readonly
CreateBuilderDelegate
createBuilderDelegate
;
internal
SingleMessageAccessor
(
string
name
)
:
base
(
name
)
{
createBuilderMethod
=
ClrType
.
GetMethod
(
"CreateBuilder"
,
new
Type
[
0
]);
//BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
internal
SingleMessageAccessor
(
string
name
)
:
base
(
name
)
{
MethodInfo
createBuilderMethod
=
ClrType
.
GetMethod
(
"CreateBuilder"
,
new
Type
[
0
]);
if
(
createBuilderMethod
==
null
)
{
throw
new
ArgumentException
(
"No public static CreateBuilder method declared in "
+
ClrType
.
Name
);
}
createBuilderDelegate
=
ReflectionUtil
.
CreateStaticUpcastDelegate
(
createBuilderMethod
);
}
/// <summary>
...
...
@@ -61,7 +60,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
}
public
override
IBuilder
CreateBuilder
()
{
return
(
IBuilder
)
createBuilderMethod
.
Invoke
(
null
,
null
);
return
createBuilderDelegate
(
);
}
}
}
\ No newline at end of file
csharp/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs
View file @
09809820
...
...
@@ -24,8 +24,9 @@ namespace Google.ProtocolBuffers.FieldAccess {
where
TMessage
:
IMessage
<
TMessage
,
TBuilder
>
where
TBuilder
:
IBuilder
<
TMessage
,
TBuilder
>
{
private
readonly
PropertyInfo
messageProperty
;
private
readonly
PropertyInfo
builderProperty
;
private
readonly
Type
clrType
;
private
readonly
GetValueDelegate
<
TMessage
>
getValueDelegate
;
private
readonly
SingleValueDelegate
<
TBuilder
>
setValueDelegate
;
private
readonly
HasDelegate
<
TMessage
>
hasDelegate
;
private
readonly
ClearDelegate
<
TBuilder
>
clearDelegate
;
...
...
@@ -34,19 +35,22 @@ namespace Google.ProtocolBuffers.FieldAccess {
/// As declared by the property.
/// </summary>
protected
Type
ClrType
{
get
{
return
messageProperty
.
Property
Type
;
}
get
{
return
clr
Type
;
}
}
internal
SinglePrimitiveAccessor
(
string
name
)
{
messageProperty
=
typeof
(
TMessage
).
GetProperty
(
name
);
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
name
);
PropertyInfo
messageProperty
=
typeof
(
TMessage
).
GetProperty
(
name
);
PropertyInfo
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
name
);
PropertyInfo
hasProperty
=
typeof
(
TMessage
).
GetProperty
(
"Has"
+
name
);
MethodInfo
clearMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Clear"
+
name
);
if
(
messageProperty
==
null
||
builderProperty
==
null
||
hasProperty
==
null
||
clearMethod
==
null
)
{
throw
new
ArgumentException
(
"Not all required properties/methods available"
);
}
clrType
=
messageProperty
.
PropertyType
;
hasDelegate
=
(
HasDelegate
<
TMessage
>)
Delegate
.
CreateDelegate
(
typeof
(
HasDelegate
<
TMessage
>),
hasProperty
.
GetGetMethod
());
clearDelegate
=
(
ClearDelegate
<
TBuilder
>)
Delegate
.
CreateDelegate
(
typeof
(
ClearDelegate
<
TBuilder
>),
clearMethod
);
getValueDelegate
=
ReflectionUtil
.
CreateUpcastDelegate
<
TMessage
>(
messageProperty
.
GetGetMethod
());
setValueDelegate
=
ReflectionUtil
.
CreateDowncastDelegate
<
TBuilder
>(
builderProperty
.
GetSetMethod
());
}
public
bool
Has
(
TMessage
message
)
{
...
...
@@ -65,11 +69,11 @@ namespace Google.ProtocolBuffers.FieldAccess {
}
public
virtual
object
GetValue
(
TMessage
message
)
{
return
messageProperty
.
GetValue
(
message
,
null
);
return
getValueDelegate
(
message
);
}
public
virtual
void
SetValue
(
TBuilder
builder
,
object
value
)
{
builderProperty
.
SetValue
(
builder
,
value
,
null
);
setValueDelegate
(
builder
,
value
);
}
#
region
Methods
only
related
to
repeated
values
...
...
@@ -77,19 +81,19 @@ namespace Google.ProtocolBuffers.FieldAccess {
throw
new
InvalidOperationException
();
}
public
object
GetRepeatedValue
(
I
Message
message
,
int
index
)
{
public
object
GetRepeatedValue
(
T
Message
message
,
int
index
)
{
throw
new
InvalidOperationException
();
}
public
void
SetRepeated
(
I
Builder
builder
,
int
index
,
object
value
)
{
public
void
SetRepeated
(
T
Builder
builder
,
int
index
,
object
value
)
{
throw
new
InvalidOperationException
();
}
public
void
AddRepeated
(
I
Builder
builder
,
object
value
)
{
public
void
AddRepeated
(
T
Builder
builder
,
object
value
)
{
throw
new
InvalidOperationException
();
}
public
object
GetRepeatedWrapper
(
I
Builder
builder
)
{
public
object
GetRepeatedWrapper
(
T
Builder
builder
)
{
throw
new
InvalidOperationException
();
}
#
endregion
...
...
csharp/ProtocolBuffers/GeneratedBuilder.cs
View file @
09809820
...
...
@@ -51,7 +51,7 @@ namespace Google.ProtocolBuffers {
// For repeated fields, the underlying list object is still modifiable at this point.
// Make sure not to expose the modifiable list to the caller.
return
field
.
IsRepeated
?
InternalFieldAccessors
[
field
].
GetRepeatedWrapper
(
this
)
?
InternalFieldAccessors
[
field
].
GetRepeatedWrapper
(
ThisBuilder
)
:
MessageBeingBuilt
[
field
];
}
set
{
...
...
@@ -92,7 +92,7 @@ namespace Google.ProtocolBuffers {
public
override
object
this
[
FieldDescriptor
field
,
int
index
]
{
get
{
return
MessageBeingBuilt
[
field
,
index
];
}
set
{
InternalFieldAccessors
[
field
].
SetRepeated
(
this
,
index
,
value
);
}
set
{
InternalFieldAccessors
[
field
].
SetRepeated
(
ThisBuilder
,
index
,
value
);
}
}
public
override
bool
HasField
(
FieldDescriptor
field
)
{
...
...
@@ -144,7 +144,7 @@ namespace Google.ProtocolBuffers {
}
public
override
TBuilder
AddRepeatedField
(
FieldDescriptor
field
,
object
value
)
{
InternalFieldAccessors
[
field
].
AddRepeated
(
this
,
value
);
InternalFieldAccessors
[
field
].
AddRepeated
(
ThisBuilder
,
value
);
return
ThisBuilder
;
}
...
...
csharp/ProtocolBuffers/GeneratedMessage.cs
View file @
09809820
...
...
@@ -112,7 +112,7 @@ namespace Google.ProtocolBuffers {
}
public
override
object
this
[
FieldDescriptor
field
,
int
index
]
{
get
{
return
InternalFieldAccessors
[
field
].
GetRepeatedValue
(
this
,
index
);
}
get
{
return
InternalFieldAccessors
[
field
].
GetRepeatedValue
(
ThisMessage
,
index
);
}
}
public
override
object
this
[
FieldDescriptor
field
]
{
...
...
csharp/ProtocolBuffers/ProtocolBuffers.csproj
View file @
09809820
...
...
@@ -72,6 +72,7 @@
<Compile
Include=
"ExtensionInfo.cs"
/>
<Compile
Include=
"ExtensionRegistry.cs"
/>
<Compile
Include=
"FieldAccess\Delegates.cs"
/>
<Compile
Include=
"FieldAccess\ReflectionUtil.cs"
/>
<Compile
Include=
"FieldAccess\SingleEnumAccessor.cs"
/>
<Compile
Include=
"FieldAccess\SingleMessageAccessor.cs"
/>
<Compile
Include=
"FieldAccess\SinglePrimitiveAccessor.cs"
/>
...
...
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