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
bea87743
Commit
bea87743
authored
Jul 23, 2015
by
Jon Skeet
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #634 from jskeet/reflection2
Reflection part 2 - for discussion
parents
7b5c3967
c1c6b2d0
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
340 additions
and
197 deletions
+340
-197
GeneratedMessageTest.cs
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+0
-160
Google.Protobuf.Test.csproj
csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+2
-1
DescriptorsTest.cs
...rp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
+19
-3
FieldAccessTest.cs
...rp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+218
-0
WrappersTest.cs
...p/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+16
-16
JsonFormatter.cs
csharp/src/Google.Protobuf/JsonFormatter.cs
+1
-1
FileDescriptor.cs
csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
+1
-1
MessageDescriptor.cs
csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
+82
-14
OneofDescriptor.cs
csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
+1
-1
No files found.
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
View file @
bea87743
...
...
@@ -597,165 +597,5 @@ namespace Google.Protobuf
Assert
.
AreEqual
(
message
,
message2
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
OneofUint32
,
message2
.
OneofFieldCase
);
}
// TODO: Consider moving these tests to a separate reflection test - although they do require generated messages.
[
Test
]
public
void
Reflection_GetValue
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
FieldAccessorsByFieldNumber
;
Assert
.
AreEqual
(
message
.
SingleBool
,
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleBytes
,
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleDouble
,
fields
[
TestAllTypes
.
SingleDoubleFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFixed32
,
fields
[
TestAllTypes
.
SingleFixed32FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFixed64
,
fields
[
TestAllTypes
.
SingleFixed64FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFloat
,
fields
[
TestAllTypes
.
SingleFloatFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleForeignEnum
,
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleForeignMessage
,
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleImportEnum
,
fields
[
TestAllTypes
.
SingleImportEnumFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleImportMessage
,
fields
[
TestAllTypes
.
SingleImportMessageFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleInt32
,
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleInt64
,
fields
[
TestAllTypes
.
SingleInt64FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleNestedEnum
,
fields
[
TestAllTypes
.
SingleNestedEnumFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleNestedMessage
,
fields
[
TestAllTypes
.
SingleNestedMessageFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SinglePublicImportMessage
,
fields
[
TestAllTypes
.
SinglePublicImportMessageFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSint32
,
fields
[
TestAllTypes
.
SingleSint32FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSint64
,
fields
[
TestAllTypes
.
SingleSint64FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleString
,
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSfixed32
,
fields
[
TestAllTypes
.
SingleSfixed32FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSfixed64
,
fields
[
TestAllTypes
.
SingleSfixed64FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleUint32
,
fields
[
TestAllTypes
.
SingleUint32FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleUint64
,
fields
[
TestAllTypes
.
SingleUint64FieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofBytes
,
fields
[
TestAllTypes
.
OneofBytesFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofString
,
fields
[
TestAllTypes
.
OneofStringFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofNestedMessage
,
fields
[
TestAllTypes
.
OneofNestedMessageFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofUint32
,
fields
[
TestAllTypes
.
OneofUint32FieldNumber
].
GetValue
(
message
));
// Just one example for repeated fields - they're all just returning the list
var
list
=
(
IList
)
fields
[
TestAllTypes
.
RepeatedInt32FieldNumber
].
GetValue
(
message
);
Assert
.
AreEqual
(
message
.
RepeatedInt32
,
list
);
Assert
.
AreEqual
(
message
.
RepeatedInt32
[
0
],
list
[
0
]);
// Just in case there was any doubt...
// Just a single map field, for the same reason
var
mapMessage
=
new
TestMap
{
MapStringString
=
{
{
"key1"
,
"value1"
},
{
"key2"
,
"value2"
}
}
};
fields
=
TestMap
.
Descriptor
.
FieldAccessorsByFieldNumber
;
var
dictionary
=
(
IDictionary
)
fields
[
TestMap
.
MapStringStringFieldNumber
].
GetValue
(
mapMessage
);
Assert
.
AreEqual
(
mapMessage
.
MapStringString
,
dictionary
);
Assert
.
AreEqual
(
"value1"
,
dictionary
[
"key1"
]);
}
[
Test
]
public
void
Reflection_Clear
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
FieldAccessorsByFieldNumber
;
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Clear
(
message
);
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
Clear
(
message
);
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
Clear
(
message
);
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
Clear
(
message
);
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
Clear
(
message
);
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
Clear
(
message
);
fields
[
TestAllTypes
.
RepeatedDoubleFieldNumber
].
Clear
(
message
);
var
expected
=
new
TestAllTypes
(
SampleMessages
.
CreateFullTestAllTypes
())
{
SingleBool
=
false
,
SingleInt32
=
0
,
SingleString
=
""
,
SingleBytes
=
ByteString
.
Empty
,
SingleForeignEnum
=
0
,
SingleForeignMessage
=
null
,
};
expected
.
RepeatedDouble
.
Clear
();
Assert
.
AreEqual
(
expected
,
message
);
// Separately, maps.
var
mapMessage
=
new
TestMap
{
MapStringString
=
{
{
"key1"
,
"value1"
},
{
"key2"
,
"value2"
}
}
};
fields
=
TestMap
.
Descriptor
.
FieldAccessorsByFieldNumber
;
fields
[
TestMap
.
MapStringStringFieldNumber
].
Clear
(
mapMessage
);
Assert
.
AreEqual
(
0
,
mapMessage
.
MapStringString
.
Count
);
}
[
Test
]
public
void
Reflection_SetValue_SingleFields
()
{
// Just a sample (primitives, messages, enums, strings, byte strings)
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
FieldAccessorsByFieldNumber
;
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
SetValue
(
message
,
false
);
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
SetValue
(
message
,
500
);
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
SetValue
(
message
,
"It's a string"
);
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
SetValue
(
message
,
ByteString
.
CopyFrom
(
99
,
98
,
97
));
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
SetValue
(
message
,
ForeignEnum
.
FOREIGN_FOO
);
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
SetValue
(
message
,
new
ForeignMessage
{
C
=
12345
});
fields
[
TestAllTypes
.
SingleDoubleFieldNumber
].
SetValue
(
message
,
20150701.5
);
var
expected
=
new
TestAllTypes
(
SampleMessages
.
CreateFullTestAllTypes
())
{
SingleBool
=
false
,
SingleInt32
=
500
,
SingleString
=
"It's a string"
,
SingleBytes
=
ByteString
.
CopyFrom
(
99
,
98
,
97
),
SingleForeignEnum
=
ForeignEnum
.
FOREIGN_FOO
,
SingleForeignMessage
=
new
ForeignMessage
{
C
=
12345
},
SingleDouble
=
20150701.5
};
Assert
.
AreEqual
(
expected
,
message
);
}
[
Test
]
public
void
Reflection_SetValue_SingleFields_WrongType
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
FieldAccessorsByFieldNumber
;
Assert
.
Throws
<
InvalidCastException
>(()
=>
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
SetValue
(
message
,
"This isn't a bool"
));
}
[
Test
]
public
void
Reflection_SetValue_MapFields
()
{
IMessage
message
=
new
TestMap
();
var
fields
=
message
.
Descriptor
.
FieldAccessorsByFieldNumber
;
Assert
.
Throws
<
InvalidOperationException
>(()
=>
fields
[
TestMap
.
MapStringStringFieldNumber
].
SetValue
(
message
,
new
Dictionary
<
string
,
string
>()));
}
[
Test
]
public
void
Reflection_SetValue_RepeatedFields
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
FieldAccessorsByFieldNumber
;
Assert
.
Throws
<
InvalidOperationException
>(()
=>
fields
[
TestAllTypes
.
RepeatedDoubleFieldNumber
].
SetValue
(
message
,
new
double
[
10
]));
}
[
Test
]
public
void
Reflection_GetValue_IncorrectType
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
FieldAccessorsByFieldNumber
;
Assert
.
Throws
<
InvalidCastException
>(()
=>
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
GetValue
(
new
TestMap
()));
}
[
Test
]
public
void
Reflection_Oneof
()
{
var
message
=
new
TestAllTypes
();
var
descriptor
=
TestAllTypes
.
Descriptor
;
Assert
.
AreEqual
(
1
,
descriptor
.
Oneofs
.
Count
);
var
oneof
=
descriptor
.
Oneofs
[
0
];
Assert
.
AreEqual
(
"oneof_field"
,
oneof
.
Name
);
Assert
.
IsNull
(
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
message
.
OneofString
=
"foo"
;
Assert
.
AreSame
(
descriptor
.
FieldAccessorsByFieldNumber
[
TestAllTypes
.
OneofStringFieldNumber
].
Descriptor
,
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
message
.
OneofUint32
=
10
;
Assert
.
AreSame
(
descriptor
.
FieldAccessorsByFieldNumber
[
TestAllTypes
.
OneofUint32FieldNumber
].
Descriptor
,
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
oneof
.
Accessor
.
Clear
(
message
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
None
,
message
.
OneofFieldCase
);
}
}
}
csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
View file @
bea87743
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project
ToolsVersion=
"4.0"
DefaultTargets=
"Build"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<PropertyGroup>
<Configuration
Condition=
" '$(Configuration)' == '' "
>
Debug
</Configuration>
...
...
@@ -82,6 +82,7 @@
<Compile
Include=
"Collections\RepeatedFieldTest.cs"
/>
<Compile
Include=
"JsonFormatterTest.cs"
/>
<Compile
Include=
"Reflection\DescriptorsTest.cs"
/>
<Compile
Include=
"Reflection\FieldAccessTest.cs"
/>
<Compile
Include=
"SampleEnum.cs"
/>
<Compile
Include=
"SampleMessages.cs"
/>
<Compile
Include=
"TestProtos\MapUnittestProto3.cs"
/>
...
...
csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
View file @
bea87743
...
...
@@ -33,6 +33,7 @@
using
System.Linq
;
using
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
using
UnitTest.Issues.TestProtos
;
namespace
Google.Protobuf.Reflection
{
...
...
@@ -102,15 +103,16 @@ namespace Google.Protobuf.Reflection
Assert
.
AreEqual
(
UnittestProto3
.
Descriptor
,
nestedType
.
File
);
Assert
.
AreEqual
(
messageType
,
nestedType
.
ContainingType
);
FieldDescriptor
field
=
messageType
.
Fields
[
0
];
FieldDescriptor
field
=
messageType
.
Fields
.
InDeclarationOrder
()
[
0
];
Assert
.
AreEqual
(
"single_int32"
,
field
.
Name
);
Assert
.
AreEqual
(
field
,
messageType
.
FindDescriptor
<
FieldDescriptor
>(
"single_int32"
));
Assert
.
Null
(
messageType
.
FindDescriptor
<
FieldDescriptor
>(
"no_such_field"
));
Assert
.
AreEqual
(
field
,
messageType
.
FindFieldByNumber
(
1
));
Assert
.
Null
(
messageType
.
FindFieldByNumber
(
571283
));
for
(
int
i
=
0
;
i
<
messageType
.
Fields
.
Count
;
i
++)
var
fieldsInDeclarationOrder
=
messageType
.
Fields
.
InDeclarationOrder
();
for
(
int
i
=
0
;
i
<
fieldsInDeclarationOrder
.
Count
;
i
++)
{
Assert
.
AreEqual
(
i
,
messageType
.
Fields
[
i
].
Index
);
Assert
.
AreEqual
(
i
,
fieldsInDeclarationOrder
[
i
].
Index
);
}
Assert
.
AreEqual
(
nestedType
,
messageType
.
NestedTypes
[
0
]);
...
...
@@ -220,5 +222,19 @@ namespace Google.Protobuf.Reflection
CollectionAssert
.
AreEquivalent
(
expectedFields
,
descriptor
.
Fields
);
}
[
Test
]
public
void
ConstructionWithoutGeneratedCodeInfo
()
{
var
data
=
UnittestIssues
.
Descriptor
.
Proto
.
ToByteArray
();
var
newDescriptor
=
Google
.
Protobuf
.
Reflection
.
FileDescriptor
.
InternalBuildGeneratedFileFrom
(
data
,
new
Reflection
.
FileDescriptor
[]
{
},
null
);
// We should still be able to get at a field...
var
messageDescriptor
=
newDescriptor
.
FindTypeByName
<
MessageDescriptor
>(
"ItemField"
);
var
fieldDescriptor
=
messageDescriptor
.
FindFieldByName
(
"item"
);
// But there shouldn't be an accessor (or a generated type for the message)
Assert
.
IsNull
(
fieldDescriptor
.
Accessor
);
Assert
.
IsNull
(
messageDescriptor
.
GeneratedType
);
}
}
}
csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
0 → 100644
View file @
bea87743
#
region
Copyright
notice
and
license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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
Google.Protobuf.TestProtos
;
using
NUnit.Framework
;
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
namespace
Google.Protobuf.Reflection
{
public
class
FieldAccessTest
{
[
Test
]
public
void
GetValue
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
Fields
;
Assert
.
AreEqual
(
message
.
SingleBool
,
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleBytes
,
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleDouble
,
fields
[
TestAllTypes
.
SingleDoubleFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFixed32
,
fields
[
TestAllTypes
.
SingleFixed32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFixed64
,
fields
[
TestAllTypes
.
SingleFixed64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleFloat
,
fields
[
TestAllTypes
.
SingleFloatFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleForeignEnum
,
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleForeignMessage
,
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleImportEnum
,
fields
[
TestAllTypes
.
SingleImportEnumFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleImportMessage
,
fields
[
TestAllTypes
.
SingleImportMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleInt32
,
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleInt64
,
fields
[
TestAllTypes
.
SingleInt64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleNestedEnum
,
fields
[
TestAllTypes
.
SingleNestedEnumFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleNestedMessage
,
fields
[
TestAllTypes
.
SingleNestedMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SinglePublicImportMessage
,
fields
[
TestAllTypes
.
SinglePublicImportMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSint32
,
fields
[
TestAllTypes
.
SingleSint32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSint64
,
fields
[
TestAllTypes
.
SingleSint64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleString
,
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSfixed32
,
fields
[
TestAllTypes
.
SingleSfixed32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleSfixed64
,
fields
[
TestAllTypes
.
SingleSfixed64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleUint32
,
fields
[
TestAllTypes
.
SingleUint32FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
SingleUint64
,
fields
[
TestAllTypes
.
SingleUint64FieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofBytes
,
fields
[
TestAllTypes
.
OneofBytesFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofString
,
fields
[
TestAllTypes
.
OneofStringFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofNestedMessage
,
fields
[
TestAllTypes
.
OneofNestedMessageFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
message
.
OneofUint32
,
fields
[
TestAllTypes
.
OneofUint32FieldNumber
].
Accessor
.
GetValue
(
message
));
// Just one example for repeated fields - they're all just returning the list
var
list
=
(
IList
)
fields
[
TestAllTypes
.
RepeatedInt32FieldNumber
].
Accessor
.
GetValue
(
message
);
Assert
.
AreEqual
(
message
.
RepeatedInt32
,
list
);
Assert
.
AreEqual
(
message
.
RepeatedInt32
[
0
],
list
[
0
]);
// Just in case there was any doubt...
// Just a single map field, for the same reason
var
mapMessage
=
new
TestMap
{
MapStringString
=
{
{
"key1"
,
"value1"
},
{
"key2"
,
"value2"
}
}
};
fields
=
TestMap
.
Descriptor
.
Fields
;
var
dictionary
=
(
IDictionary
)
fields
[
TestMap
.
MapStringStringFieldNumber
].
Accessor
.
GetValue
(
mapMessage
);
Assert
.
AreEqual
(
mapMessage
.
MapStringString
,
dictionary
);
Assert
.
AreEqual
(
"value1"
,
dictionary
[
"key1"
]);
}
[
Test
]
public
void
Clear
()
{
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
Fields
;
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
Accessor
.
Clear
(
message
);
fields
[
TestAllTypes
.
RepeatedDoubleFieldNumber
].
Accessor
.
Clear
(
message
);
var
expected
=
new
TestAllTypes
(
SampleMessages
.
CreateFullTestAllTypes
())
{
SingleBool
=
false
,
SingleInt32
=
0
,
SingleString
=
""
,
SingleBytes
=
ByteString
.
Empty
,
SingleForeignEnum
=
0
,
SingleForeignMessage
=
null
,
};
expected
.
RepeatedDouble
.
Clear
();
Assert
.
AreEqual
(
expected
,
message
);
// Separately, maps.
var
mapMessage
=
new
TestMap
{
MapStringString
=
{
{
"key1"
,
"value1"
},
{
"key2"
,
"value2"
}
}
};
fields
=
TestMap
.
Descriptor
.
Fields
;
fields
[
TestMap
.
MapStringStringFieldNumber
].
Accessor
.
Clear
(
mapMessage
);
Assert
.
AreEqual
(
0
,
mapMessage
.
MapStringString
.
Count
);
}
[
Test
]
public
void
SetValue_SingleFields
()
{
// Just a sample (primitives, messages, enums, strings, byte strings)
var
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
TestAllTypes
.
Descriptor
.
Fields
;
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
SetValue
(
message
,
false
);
fields
[
TestAllTypes
.
SingleInt32FieldNumber
].
Accessor
.
SetValue
(
message
,
500
);
fields
[
TestAllTypes
.
SingleStringFieldNumber
].
Accessor
.
SetValue
(
message
,
"It's a string"
);
fields
[
TestAllTypes
.
SingleBytesFieldNumber
].
Accessor
.
SetValue
(
message
,
ByteString
.
CopyFrom
(
99
,
98
,
97
));
fields
[
TestAllTypes
.
SingleForeignEnumFieldNumber
].
Accessor
.
SetValue
(
message
,
ForeignEnum
.
FOREIGN_FOO
);
fields
[
TestAllTypes
.
SingleForeignMessageFieldNumber
].
Accessor
.
SetValue
(
message
,
new
ForeignMessage
{
C
=
12345
});
fields
[
TestAllTypes
.
SingleDoubleFieldNumber
].
Accessor
.
SetValue
(
message
,
20150701.5
);
var
expected
=
new
TestAllTypes
(
SampleMessages
.
CreateFullTestAllTypes
())
{
SingleBool
=
false
,
SingleInt32
=
500
,
SingleString
=
"It's a string"
,
SingleBytes
=
ByteString
.
CopyFrom
(
99
,
98
,
97
),
SingleForeignEnum
=
ForeignEnum
.
FOREIGN_FOO
,
SingleForeignMessage
=
new
ForeignMessage
{
C
=
12345
},
SingleDouble
=
20150701.5
};
Assert
.
AreEqual
(
expected
,
message
);
}
[
Test
]
public
void
SetValue_SingleFields_WrongType
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidCastException
>(()
=>
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
SetValue
(
message
,
"This isn't a bool"
));
}
[
Test
]
public
void
SetValue_MapFields
()
{
IMessage
message
=
new
TestMap
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidOperationException
>(()
=>
fields
[
TestMap
.
MapStringStringFieldNumber
].
Accessor
.
SetValue
(
message
,
new
Dictionary
<
string
,
string
>()));
}
[
Test
]
public
void
SetValue_RepeatedFields
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidOperationException
>(()
=>
fields
[
TestAllTypes
.
RepeatedDoubleFieldNumber
].
Accessor
.
SetValue
(
message
,
new
double
[
10
]));
}
[
Test
]
public
void
GetValue_IncorrectType
()
{
IMessage
message
=
SampleMessages
.
CreateFullTestAllTypes
();
var
fields
=
message
.
Descriptor
.
Fields
;
Assert
.
Throws
<
InvalidCastException
>(()
=>
fields
[
TestAllTypes
.
SingleBoolFieldNumber
].
Accessor
.
GetValue
(
new
TestMap
()));
}
[
Test
]
public
void
Oneof
()
{
var
message
=
new
TestAllTypes
();
var
descriptor
=
TestAllTypes
.
Descriptor
;
Assert
.
AreEqual
(
1
,
descriptor
.
Oneofs
.
Count
);
var
oneof
=
descriptor
.
Oneofs
[
0
];
Assert
.
AreEqual
(
"oneof_field"
,
oneof
.
Name
);
Assert
.
IsNull
(
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
message
.
OneofString
=
"foo"
;
Assert
.
AreSame
(
descriptor
.
Fields
[
TestAllTypes
.
OneofStringFieldNumber
],
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
message
.
OneofUint32
=
10
;
Assert
.
AreSame
(
descriptor
.
Fields
[
TestAllTypes
.
OneofUint32FieldNumber
],
oneof
.
Accessor
.
GetCaseFieldDescriptor
(
message
));
oneof
.
Accessor
.
Clear
(
message
);
Assert
.
AreEqual
(
TestAllTypes
.
OneofFieldOneofCase
.
None
,
message
.
OneofFieldCase
);
}
[
Test
]
public
void
FieldDescriptor_ByName
()
{
var
descriptor
=
TestAllTypes
.
Descriptor
;
Assert
.
AreSame
(
descriptor
.
Fields
[
TestAllTypes
.
SingleBoolFieldNumber
],
descriptor
.
Fields
[
"single_bool"
]);
}
[
Test
]
public
void
FieldDescriptor_NotFound
()
{
var
descriptor
=
TestAllTypes
.
Descriptor
;
Assert
.
Throws
<
KeyNotFoundException
>(()
=>
descriptor
.
Fields
[
999999
].
ToString
());
Assert
.
Throws
<
KeyNotFoundException
>(()
=>
descriptor
.
Fields
[
"not found"
].
ToString
());
}
}
}
csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
View file @
bea87743
...
...
@@ -192,23 +192,23 @@ namespace Google.Protobuf.WellKnownTypes
Uint32Field
=
3
,
Uint64Field
=
4
};
var
fields
=
TestWellKnownTypes
.
Descriptor
.
Field
AccessorsByFieldNumber
;
var
fields
=
TestWellKnownTypes
.
Descriptor
.
Field
s
;
Assert
.
AreEqual
(
"x"
,
fields
[
TestWellKnownTypes
.
StringFieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
ByteString
.
CopyFrom
(
1
,
2
,
3
),
fields
[
TestWellKnownTypes
.
BytesFieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
true
,
fields
[
TestWellKnownTypes
.
BoolFieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
12.5f
,
fields
[
TestWellKnownTypes
.
FloatFieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
12.25d
,
fields
[
TestWellKnownTypes
.
DoubleFieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
1
,
fields
[
TestWellKnownTypes
.
Int32FieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
2L
,
fields
[
TestWellKnownTypes
.
Int64FieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
3U
,
fields
[
TestWellKnownTypes
.
Uint32FieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
4U
L
,
fields
[
TestWellKnownTypes
.
Uint64FieldFieldNumber
].
GetValue
(
message
));
Assert
.
AreEqual
(
"x"
,
fields
[
TestWellKnownTypes
.
StringFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
ByteString
.
CopyFrom
(
1
,
2
,
3
),
fields
[
TestWellKnownTypes
.
BytesFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
true
,
fields
[
TestWellKnownTypes
.
BoolFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
12.5f
,
fields
[
TestWellKnownTypes
.
FloatFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
12.25d
,
fields
[
TestWellKnownTypes
.
DoubleFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
1
,
fields
[
TestWellKnownTypes
.
Int32FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
2L
,
fields
[
TestWellKnownTypes
.
Int64FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
3U
,
fields
[
TestWellKnownTypes
.
Uint32FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
AreEqual
(
4U
L
,
fields
[
TestWellKnownTypes
.
Uint64FieldFieldNumber
].
Accessor
.
GetValue
(
message
));
// And a couple of null fields...
message
.
StringField
=
null
;
message
.
FloatField
=
null
;
Assert
.
IsNull
(
fields
[
TestWellKnownTypes
.
StringFieldFieldNumber
].
GetValue
(
message
));
Assert
.
IsNull
(
fields
[
TestWellKnownTypes
.
FloatFieldFieldNumber
].
GetValue
(
message
));
Assert
.
IsNull
(
fields
[
TestWellKnownTypes
.
StringFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
Assert
.
IsNull
(
fields
[
TestWellKnownTypes
.
FloatFieldFieldNumber
].
Accessor
.
GetValue
(
message
));
}
[
Test
]
...
...
@@ -216,8 +216,8 @@ namespace Google.Protobuf.WellKnownTypes
{
// Just a single example... note that we can't have a null value here
var
message
=
new
RepeatedWellKnownTypes
{
Int32Field
=
{
1
,
2
}
};
var
fields
=
RepeatedWellKnownTypes
.
Descriptor
.
Field
AccessorsByFieldNumber
;
var
list
=
(
IList
)
fields
[
RepeatedWellKnownTypes
.
Int32FieldFieldNumber
].
GetValue
(
message
);
var
fields
=
RepeatedWellKnownTypes
.
Descriptor
.
Field
s
;
var
list
=
(
IList
)
fields
[
RepeatedWellKnownTypes
.
Int32FieldFieldNumber
].
Accessor
.
GetValue
(
message
);
CollectionAssert
.
AreEqual
(
new
[]
{
1
,
2
},
list
);
}
...
...
@@ -226,8 +226,8 @@ namespace Google.Protobuf.WellKnownTypes
{
// Just a single example... note that we can't have a null value here
var
message
=
new
MapWellKnownTypes
{
Int32Field
=
{
{
1
,
2
},
{
3
,
null
}
}
};
var
fields
=
MapWellKnownTypes
.
Descriptor
.
Field
AccessorsByFieldNumber
;
var
dictionary
=
(
IDictionary
)
fields
[
MapWellKnownTypes
.
Int32FieldFieldNumber
].
GetValue
(
message
);
var
fields
=
MapWellKnownTypes
.
Descriptor
.
Field
s
;
var
dictionary
=
(
IDictionary
)
fields
[
MapWellKnownTypes
.
Int32FieldFieldNumber
].
Accessor
.
GetValue
(
message
);
Assert
.
AreEqual
(
2
,
dictionary
[
1
]);
Assert
.
IsNull
(
dictionary
[
3
]);
Assert
.
IsTrue
(
dictionary
.
Contains
(
3
));
...
...
csharp/src/Google.Protobuf/JsonFormatter.cs
View file @
bea87743
...
...
@@ -140,7 +140,7 @@ namespace Google.Protobuf
var
fields
=
message
.
Descriptor
.
Fields
;
bool
first
=
true
;
// First non-oneof fields
foreach
(
var
field
in
fields
)
foreach
(
var
field
in
fields
.
InFieldNumberOrder
()
)
{
var
accessor
=
field
.
Accessor
;
// Oneofs are written later
...
...
csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
View file @
bea87743
...
...
@@ -231,7 +231,7 @@ namespace Google.Protobuf.Reflection
/// Finds a type (message, enum, service or extension) in the file by name. Does not find nested types.
/// </summary>
/// <param name="name">The unqualified type name to look for.</param>
/// <typeparam name="T">The type of descriptor to look for
(or ITypeDescriptor for any)
</typeparam>
/// <typeparam name="T">The type of descriptor to look for</typeparam>
/// <returns>The type's descriptor, or null if not found.</returns>
public
T
FindTypeByName
<
T
>(
String
name
)
where
T
:
class
,
IDescriptor
...
...
csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
View file @
bea87743
...
...
@@ -33,6 +33,7 @@
using
Google.Protobuf.Collections
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.ObjectModel
;
using
System.Linq
;
namespace
Google.Protobuf.Reflection
...
...
@@ -60,11 +61,12 @@ namespace Google.Protobuf.Reflection
private
readonly
MessageDescriptor
containingType
;
private
readonly
IList
<
MessageDescriptor
>
nestedTypes
;
private
readonly
IList
<
EnumDescriptor
>
enumTypes
;
private
readonly
IList
<
FieldDescriptor
>
fields
;
private
readonly
IList
<
FieldDescriptor
>
fieldsInDeclarationOrder
;
private
readonly
IList
<
FieldDescriptor
>
fieldsInNumberOrder
;
private
readonly
FieldCollection
fields
;
private
readonly
IList
<
OneofDescriptor
>
oneofs
;
// CLR representation of the type described by this descriptor, if any.
private
readonly
Type
generatedType
;
private
IDictionary
<
int
,
IFieldAccessor
>
fieldAccessorsByFieldNumber
;
internal
MessageDescriptor
(
DescriptorProto
proto
,
FileDescriptor
file
,
MessageDescriptor
parent
,
int
typeIndex
,
GeneratedCodeInfo
generatedCodeInfo
)
:
base
(
file
,
file
.
ComputeFullName
(
parent
,
proto
.
Name
),
typeIndex
)
...
...
@@ -89,11 +91,13 @@ namespace Google.Protobuf.Reflection
(
type
,
index
)
=>
new
EnumDescriptor
(
type
,
file
,
this
,
index
,
generatedCodeInfo
==
null
?
null
:
generatedCodeInfo
.
NestedEnums
[
index
]));
fields
=
DescriptorUtil
.
ConvertAndMakeReadOnly
(
fields
InDeclarationOrder
=
DescriptorUtil
.
ConvertAndMakeReadOnly
(
proto
.
Field
,
(
field
,
index
)
=>
new
FieldDescriptor
(
field
,
file
,
this
,
index
,
generatedCodeInfo
==
null
?
null
:
generatedCodeInfo
.
PropertyNames
[
index
]));
fieldsInNumberOrder
=
new
ReadOnlyCollection
<
FieldDescriptor
>(
fieldsInDeclarationOrder
.
OrderBy
(
field
=>
field
.
FieldNumber
).
ToArray
());
file
.
DescriptorPool
.
AddSymbol
(
this
);
fields
=
new
FieldCollection
(
this
);
}
/// <summary>
...
...
@@ -136,9 +140,9 @@ namespace Google.Protobuf.Reflection
}
/// <value>
/// A
n unmodifiable list of this message type's fields
.
/// A
collection of fields, which can be retrieved by name or field number
.
/// </value>
public
IList
<
FieldDescriptor
>
Fields
public
FieldCollection
Fields
{
get
{
return
fields
;
}
}
...
...
@@ -164,13 +168,6 @@ namespace Google.Protobuf.Reflection
get
{
return
oneofs
;
}
}
/// <summary>
/// Returns a map from field number to accessor.
/// TODO: Revisit this. It's mostly in place to make the transition from FieldAccessorTable
/// to descriptor-based reflection simple in terms of tests. Work out what we really want.
/// </summary>
public
IDictionary
<
int
,
IFieldAccessor
>
FieldAccessorsByFieldNumber
{
get
{
return
fieldAccessorsByFieldNumber
;
}
}
/// <summary>
/// Finds a field by field name.
/// </summary>
...
...
@@ -213,7 +210,7 @@ namespace Google.Protobuf.Reflection
message
.
CrossLink
();
}
foreach
(
FieldDescriptor
field
in
fields
)
foreach
(
FieldDescriptor
field
in
fields
InDeclarationOrder
)
{
field
.
CrossLink
();
}
...
...
@@ -222,8 +219,79 @@ namespace Google.Protobuf.Reflection
{
oneof
.
CrossLink
();
}
}
/// <summary>
/// A collection to simplify retrieving the field accessor for a particular field.
/// </summary>
public
sealed
class
FieldCollection
{
private
readonly
MessageDescriptor
messageDescriptor
;
internal
FieldCollection
(
MessageDescriptor
messageDescriptor
)
{
this
.
messageDescriptor
=
messageDescriptor
;
}
/// <value>
/// Returns the fields in the message as an immutable list, in the order in which they
/// are declared in the source .proto file.
/// </value>
public
IList
<
FieldDescriptor
>
InDeclarationOrder
()
{
return
messageDescriptor
.
fieldsInDeclarationOrder
;
}
/// <value>
/// Returns the fields in the message as an immutable list, in ascending field number
/// order. Field numbers need not be contiguous, so there is no direct mapping from the
/// index in the list to the field number; to retrieve a field by field number, it is better
/// to use the <see cref="FieldCollection"/> indexer.
/// </value>
public
IList
<
FieldDescriptor
>
InFieldNumberOrder
()
{
return
messageDescriptor
.
fieldsInDeclarationOrder
;
}
/// <summary>
/// Retrieves the descriptor for the field with the given number.
/// </summary>
/// <param name="number">Number of the field to retrieve the descriptor for</param>
/// <returns>The accessor for the given field</returns>
/// <exception cref="KeyNotFoundException">The message descriptor does not contain a field
/// with the given number</exception>
public
FieldDescriptor
this
[
int
number
]
{
get
{
var
fieldDescriptor
=
messageDescriptor
.
FindFieldByNumber
(
number
);
if
(
fieldDescriptor
==
null
)
{
throw
new
KeyNotFoundException
(
"No such field number"
);
}
return
fieldDescriptor
;
}
}
fieldAccessorsByFieldNumber
=
new
ReadOnlyDictionary
<
int
,
IFieldAccessor
>(
fields
.
ToDictionary
(
field
=>
field
.
FieldNumber
,
field
=>
field
.
Accessor
));
/// <summary>
/// Retrieves the descriptor for the field with the given name.
/// </summary>
/// <param name="number">Number of the field to retrieve the descriptor for</param>
/// <returns>The descriptor for the given field</returns>
/// <exception cref="KeyNotFoundException">The message descriptor does not contain a field
/// with the given name</exception>
public
FieldDescriptor
this
[
string
name
]
{
get
{
var
fieldDescriptor
=
messageDescriptor
.
FindFieldByName
(
name
);
if
(
fieldDescriptor
==
null
)
{
throw
new
KeyNotFoundException
(
"No such field name"
);
}
return
fieldDescriptor
;
}
}
}
}
}
csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
View file @
bea87743
...
...
@@ -70,7 +70,7 @@ namespace Google.Protobuf.Reflection
internal
void
CrossLink
()
{
List
<
FieldDescriptor
>
fieldCollection
=
new
List
<
FieldDescriptor
>();
foreach
(
var
field
in
ContainingType
.
Fields
)
foreach
(
var
field
in
ContainingType
.
Fields
.
InDeclarationOrder
()
)
{
if
(
field
.
ContainingOneof
==
this
)
{
...
...
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