Compare commits

..

432 commits

Author SHA1 Message Date
Roman Kuznetsov
bda4bb9068 Put v3.3.0 at the top of master branch to simplify usage of this repository as submodule 2017-07-08 16:55:13 +03:00
Adam Cozzette
bd5ab154da Merge pull request #2482 from andreaseger/fix_ruby_timestamp_accuracy
[Ruby] fix floating point accuracy problem in Timestamp#to_f
2017-07-06 08:11:50 -07:00
MaDuo
6bd51a59df add Grpc Protobuf validation (#3311)
* add Grpc Protobuf validation
2017-07-05 11:31:32 -07:00
Thomas Van Lenten
e264b20e69 Merge pull request #3315 from thomasvl/mutate_unknowns
Expose the initializer for unknown fields.
2017-07-05 11:25:38 -04:00
Thomas Van Lenten
b30dee3ea6 Expose the initializer for unknown fields. 2017-07-05 11:16:34 -04:00
Jon Skeet
cdd524a0bd Ensure leaveOpen is true when writing to a buffer
Note that the compatibility tests have had to cahnge as well, to
cope with internal changes. (The test project has access to
internals in the main project.)

Fixes #3209.
2017-07-04 06:42:45 +01:00
Jon Skeet
62d7fe5697 Make Any easier to work with in C#
- Add a TryUnpack method which doesn't throw if the type is wrong
- Make GetTypeName public for easier determination of the message type

Fixes #3294.
2017-07-03 12:16:40 +01:00
Paul Yang
ecca6ea95d Add json encode/decode for php. (#3226)
* Add json encode/decode for php.

* Fix php conformance test on 32-bit machines.

* Fix conformance test for c extension.

* Fix comments
2017-06-30 12:14:09 -07:00
Thomas Van Lenten
5a52b3588d Merge pull request #3287 from sergiocampama/initialized
Add initialized as a reserved keyword as that's the actual property name
2017-06-29 11:52:37 -04:00
Sergio Campama
e55782fa95 Add initialized as a reserved keyword as that's the actual property name 2017-06-29 11:49:36 -04:00
Paul Yang
176bac6dac Add scripts to build python wheel for linux. (#2693)
* Add scripts to build python wheel for linux.
Followed PEP513.

* Fix dist check for new added files.

* Update README for usage example.
2017-06-28 15:22:19 -07:00
Brent Shaffer
12acbc2678 adds PHPDoc @return and @param for getters and setters respectively (#3131)
* adds PHPDoc @return and @param for getters and setters respectively

* addresses changes in PR review

* adds documentation tests

* Update php_generator:

- Prepend \ to names where required
- Remove <pre> tags
- Update protobuf field comments

* Updates class files with the protobuf changes

* Addresses review comments

* removes Protobuf Type line from PHP generated classes

* fixes phpdoc test

* adds array types to phpdoc
2017-06-27 16:28:28 -07:00
Feng Xiao
097bfb53d1 Merge pull request #3084 from lukaszx0/patch-1
Workaround the docker bug when compiling artifacts
2017-06-26 10:48:22 -07:00
Paul Yang
dd7265e1a2 Merge pull request #3264 from TeBoring/php-bug
Enusre public header and generated code have no implicit converion.
2017-06-24 12:20:57 -07:00
Bo Yang
e3c807d4e7 Fix more implicit type conversions in public headers and generated code. 2017-06-24 11:28:13 -07:00
Feng Xiao
1a7e49d462 Merge pull request #2968 from ngg/cpp-proper-fwd
C++: Do not forward-declare dependencies in generated .h files
2017-06-23 15:08:04 -07:00
Bo Yang
9c0b35cf62 Enusre public header and generated code have no implicit converion. 2017-06-23 11:58:05 -07:00
Feng Xiao
f752d816b7 Merge pull request #3266 from mbrickn/patch-1
Updated links to use https
2017-06-23 10:39:42 -07:00
Maxwell Paul Brickner
d07efbad91 Updated links to use https
Howdy!

I just updated some links to use https instead of http.

Thanks! ^ _ ^
2017-06-23 09:25:03 -04:00
Thomas Van Lenten
eca0f4ee91 Merge pull request #3261 from thomasvl/super_oddcase
If we fail to get a descriptor just super the method resolving.
2017-06-22 10:34:10 -04:00
Thomas Van Lenten
db45687a38 If we fail to get a descriptor just super the method resolving.
This should never happen, but if someone is swizzling or do other
hooking of methods, anything is possible, so this seems slighty
safer than they returning NO.
2017-06-22 10:18:00 -04:00
Ryan Gordon
703cd8e11c Switch to addEnumType to fix fatal error (#3225)
* Switch to addEnumType to fix fatal error

* Fixing more cases of HHVM incompatibility

* Updating tests to be hhvm compatible

* Fixing tests

* Fixing merge

* Don't use call_user_func, should hopefully fix tests

* Fixing spelling

* Fixing another misspelling in a test

* Fixing placement of append and kvUpdate functions

* Actually fix function helpers

* Remove double addEnumType. How did this ever work?

* Fixing a couple more tests

* Only use the setter if the return value isn't an object
2017-06-19 18:15:49 -07:00
Joshua Haberman
1325588982 Updated upb to fix JSON conformance issues. (#3206)
* Fixed a bunch of Ruby conformance errors.

* Fixed some more Ruby conformance errors in JSON.
2017-06-19 15:13:24 -07:00
Feng Xiao
c2fdef05cf Merge pull request #3243 from yjjnls/master
replenish missed header files in install step
2017-06-19 11:18:45 -07:00
Thomas Van Lenten
73b7cc0007 Merge pull request #3244 from thomasvl/complete_docs
ObjC: Document the exceptions on some of the writing apis.
2017-06-19 10:34:25 -04:00
Thomas Van Lenten
5fd71ce631 ObjC: Document the exceptions on some of the writing apis. 2017-06-19 10:33:45 -04:00
Thomas Van Lenten
72e293a28f Merge pull request #3240 from thomasvl/float_fun
Raise the number of digits used for floats.
2017-06-19 08:23:37 -04:00
yjjnls
8f367c0b2d replenish missed header files in install step
install 'generated_message_table_driven.h' and 'metadata_lite.h', they are included when compiling the files generated using protoc.exe 3.3.0
2017-06-19 14:15:54 +08:00
Jeff Ching
5729cf77f6 Remove inclusion of ext/json/php_json.h. (#3241)
That implementation of json is not being used - this extension is using
a json encoder/decoder provided by 'upb'.
2017-06-17 11:01:16 -07:00
Thomas Van Lenten
dd19b876d4 Raise the number of digits used for floats.
About 1.5% of all IEEE754 single-precision numbers require nine
decimal digits to represent accurately.
2017-06-16 15:24:33 -04:00
Feng Xiao
710543d915 Merge pull request #3237 from calder/patch-1
Qualify string in java_options.h
2017-06-16 11:39:11 -07:00
Feng Xiao
491b32041d Merge pull request #3236 from buchgr/bazel-links
bazel: add bazel symlinks to .gitignore
2017-06-16 11:38:15 -07:00
Feng Xiao
888e287e3b Merge pull request #3235 from buchgr/java-target
bazel: Make compiled jars java 6 binary compatible.
2017-06-16 11:37:48 -07:00
Calder Coalson
4b36d4006b Qualify string in java_options.h
Building the protobuf compiler with Bazel fails to resolve the unqualifed "string"s in java_options.h:

```
ERROR: .../external/com_google_protobuf/BUILD:248:1: C++ compilation of rule '@com_google_protobuf//:protoc_lib' failed: Process exited with status 1 [sandboxed].
In file included from external/com_google_protobuf/src/google/protobuf/compiler/java/java_context.h:41:0,
                 from external/com_google_protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.cc:38:
external/com_google_protobuf/src/google/protobuf/compiler/java/java_options.h:59:3: error: 'string' does not name a type
   string annotation_list_file;
   ^
external/com_google_protobuf/src/google/protobuf/compiler/java/java_options.h:62:3: error: 'string' does not name a type
   string output_list_file;
   ^
Use --strategy=CppCompile=standalone to disable sandboxing for the failing actions.
INFO: Elapsed time: 41.487s, Critical Path: 6.20s
//interpreter:eval_test                                               NO STATUS

Executed 0 out of 1 test: 1 was skipped.
```
2017-06-16 07:06:09 -07:00
Jakob Buchgraber
36e63da632 bazel: Make compiled jars java 6 binary compatible.
See: https://github.com/bazelbuild/bazel/issues/3198
2017-06-16 12:50:35 +02:00
Jakob Buchgraber
d0e6f3b9ab bazel: add bazel symlinks to .gitignore 2017-06-16 12:39:32 +02:00
Paul Yang
91bf623aa1 Fix php jenkins test (#3233)
Update commit id to upload latest composer.
Compile php with bc-math for future json support.
2017-06-15 13:04:08 -07:00
michaelbausor
8d97b3d8b5 Fix incorrect function call (#3232) 2017-06-15 10:49:24 -07:00
Brent Shaffer
b9b34e9b11 Follows proper autoloading standards (#3123)
* Follows proper autoloading standards
 - Splits PHP classes in descriptor.php into separate files
 - Splits MapFieldIter and RepeatedFieldIter into separate files
 - Moves descriptor.php to Internal/functions.php
 - Moves all namespaced functions into Iternal/functions.php

* fixes Makefile.am for added php files

* [PHP] moves all functions to GPBUtil

* removes description.php from the makefile
2017-06-14 15:57:11 -07:00
Thomas Van Lenten
09d2994b1f Merge pull request #3228 from thomasvl/add_tvos_to_podspec
Add tvOS to the podspec.
2017-06-14 15:57:55 -04:00
Thomas Van Lenten
6ecf38f427 Add tvOS to the podspec.
Fixes https://github.com/google/protobuf/issues/3217
2017-06-14 15:56:41 -04:00
Feng Xiao
c722c3d294 Merge pull request #3216 from traversaro/patch-1
Export symbols used in inline functions
2017-06-12 10:26:57 -07:00
Silvio Traversaro
9094bf0f7e Export symbols used in inline functions
fixed_address_empty_string symbol is used in an inline function.
We have to export it to avoid undefined reference link errors.
2017-06-12 17:09:55 +02:00
Gergely Nagy
9ba7d1c038 C++: Do not forward-declare dependencies in generated .h files 2017-06-12 14:34:51 +02:00
Adam Cozzette
96095f3a85 Merge pull request #3176 from acozzette/fix-3114
Ensure that for Java, imports of .proto files with empty packages works
2017-06-07 15:15:34 -07:00
Feng Xiao
c202b06de9 Merge pull request #3196 from matt-kwong/kokoro
Add continuous testing config files for Kokoro
2017-06-07 11:09:37 -07:00
Matt Kwong
0871e6a808 Add continuous testing config files for Kokoro 2017-06-07 11:08:00 -07:00
Feng Xiao
d4d41af19b Merge pull request #3191 from matt-kwong/kokoro
Add MacOS and Linux tests to Kokoro
2017-06-06 16:44:30 -07:00
Matt Kwong
6156af10e8 Add MacOS and Linux tests to Kokoro 2017-06-06 15:09:02 -07:00
Thomas Van Lenten
d555775836 Merge pull request #3189 from thomasvl/objc_proto3_unknown_fields
ObjC: Preserve unknown fields in proto3 syntax files.
2017-06-06 15:31:20 -04:00
Feng Xiao
2aeb4ab9c7 Merge pull request #3160 from meteorcloudy/winbuild
Refactor cc options in BUILD file for Windows
2017-06-06 10:31:21 -07:00
Adam Cozzette
ddbe36003e Merge pull request #3159 from yeswalrus/new-generate
CMake: Add modern protobuf_generate
2017-06-06 09:13:31 -07:00
Thomas Van Lenten
1d0988b8ef ObjC: Preserve unknown fields in proto3 syntax files.
As announced: https://groups.google.com/forum/#!topic/protobuf/VX5qEmTW3y0

The ObjC side of https://github.com/google/protobuf/issues/272
2017-06-06 10:44:14 -04:00
Thomas Van Lenten
516a81a424 Merge pull request #3190 from thomasvl/objc_IllegalZeroFieldNum
Properly error on a tag with field number zero.
2017-06-06 10:41:04 -04:00
Thomas Van Lenten
ecc0f54127 Properly error on a tag with field number zero. 2017-06-06 10:14:41 -04:00
Adam Cozzette
656dedbf07 Merge pull request #3157 from yeswalrus/fix-version-check
Fix CMake version check
2017-06-05 14:19:23 -07:00
Paul Yang
6f325805c0 Add new file option php_namespace. (#3162)
* Add new file option php_namespace.

Use this option to change the namespace of php generated classes.
Default is empty. When this option is empty, the package name will be
used for determining the namespace.

* Uncomment commented tests

* Revert gdb test change

* Update csharp descriptor.

* Add test for empty php_namespace.
2017-06-05 00:10:18 -07:00
Walter Gray
df3f8cf6dd fix check_and_save_build_option not correctly exporting build options 2017-06-02 19:59:03 -07:00
Walter Gray
0336770801 add protobuf_generate function, allows use of target_sources where available 2017-06-02 19:57:08 -07:00
Adam Cozzette
e9c15d601e Ensure that for Java, imports of .proto files with empty packages works
This fixes a compiler bug that caused a Java syntax error when one .proto file
would import another one with an empty package and java_package. This fixes
issue #3114.
2017-06-02 13:45:57 -07:00
Thomas Van Lenten
fbaad3617f Merge pull request #3169 from dmaclach/master
Optimize GPBDictionary.m codegen to reduce size of library
2017-06-01 15:34:00 -04:00
Thomas Van Lenten
63a97289dc Merge pull request #3170 from thomasvl/int64_map_issue
Fix some cases of reading of 64bit map values.
2017-06-01 14:27:24 -04:00
Thomas Van Lenten
46f36d79a2 Fix some cases of reading of 64bit map values.
Fixes https://github.com/google/protobuf/issues/3164.
2017-06-01 14:25:45 -04:00
Dave MacLachlan
ea43e0c5e8 Optimize GPBDictionary.m codegen to reduce size of overall library by 46K per architecture. 2017-06-01 10:28:06 -07:00
Yun Peng
0b059a3d8a Refactor cc options in BUILD file for Windows
Don't put gcc warnings options in copts, so that protobuf is able to
build by MSVC toolchain without python wrappers.
2017-05-31 14:01:30 +02:00
Walter Gray
a183a0df61 Fix the check_and_save_build_option macro never evaluating to true 2017-05-30 15:04:11 -07:00
Walter Gray
faa53989cb fix check_and_save_build_option not correctly exporting build options 2017-05-30 15:04:11 -07:00
Walter Gray
ae85cb8ef3 Fix find module not working when no version number was given 2017-05-30 15:04:11 -07:00
Wayne Zhang
d6470abef1 not to use std::random_device for map.Seed(). (#3133)
* not to use std::random_device for map.Seed().

* remove include random
2017-05-30 11:18:23 -07:00
Adam Cozzette
e222997c5b Merge pull request #3149 from KarrokDC/master
Add headers as part of cmake project generation
2017-05-30 09:27:21 -07:00
Paul Yang
1e86ef4e9f Oneof field should be serialized even it's equal to default. (#3153) 2017-05-29 22:04:20 -07:00
Paul Yang
282fb9e68e Add ARRAY for reserved name (#3150) 2017-05-29 15:30:47 -07:00
Brent Shaffer
4d5daf4ef9 Adds fluent setters for PHP (#3130) 2017-05-29 10:39:14 -07:00
Dennis Cappendijk
4eb02fe31e Add headers as part of cmake project
tested only on windows with visual studio 2015 as generator
2017-05-29 17:34:08 +02:00
Adam Cozzette
4674cc7c07 Merge pull request #3113 from phst/master
Improve fix for https://github.com/google/protobuf/issues/295
2017-05-26 09:50:18 -07:00
John Brock
95749d5af6 update csharp README and fix .NET 3.5 build error 2017-05-25 20:20:31 +01:00
Jon Skeet
0b07d7eb9e Add IncludeSource in csproj as per review comments 2017-05-24 09:07:33 +01:00
Jon Skeet
f26e8c2ae0 Convert C# projects to MSBuild (csproj) format
This has one important packaging change: the netstandard version now
depends (implicitly) on netstandard1.6.1 rather than on individual
packages. This is the preferred style of dependency, and shouldn't
affect any users - see http://stackoverflow.com/questions/42946951
for details.

The tests are still NUnit, but NUnit doesn't support "dotnet test"
yet; the test project is now an executable using NUnitLite. (When
NUnit supports dotnet test, we can adapt to it.)

Note that the project will now only work in Visual Studio 2017 (and
Visual Studio Code, and from the command line with the .NET Core
1.0.0 SDK); Visual Studio 2015 does *not* support this project file
format.
2017-05-24 09:07:33 +01:00
brian-peloton
40da1ed572 Removing undefined behavior and compiler warnings (#1315)
* Comment out unused arguments.

These last few are all that's needed to compile with -Wunused-arguments.

* Fix missing struct field initializer.

With this fix, everything compiles with -Wmissing-field-initializers.

* Add support for disabling unaligned memory accesses on x86 too.

ubsan doesn't like these because they are technically undefined
behavior, so -DGOOGLE_PROTOBUF_DONT_USE_UNALIGNED will disable them easily.

* Avoid undefined integer overflow.

ubsan catches all of these.
2017-05-23 16:22:57 -07:00
Feng Xiao
ba987a7e2d Merge pull request #3126 from mbrukman/fix-readme-formatting
Fix Markdown formatting in README.
2017-05-23 14:04:08 -07:00
Feng Xiao
c5125f371d Merge pull request #3117 from KarrokDC/master
Show help if protoc is called without any arguments
2017-05-23 13:39:56 -07:00
Thomas Van Lenten
d2c1865374 Merge pull request #3103 from sergiocampama/perf
Adds serial and parallel parsing tests.
2017-05-23 15:14:08 -04:00
Sergio Campama
2465ae7e23 Adds serial and parallel parsing tests to check if parallel parsing is faster than serial parsing, which it should 2017-05-23 11:04:35 -04:00
Misha Brukman
677557009c Fix Markdown formatting in README.
Fix indentation to enable code formatting for sample command lines to set them
visually apart from the surrounding text, and make it easy to copy-paste.

Add code formatting for env vars, paths, binary and library names for
readability.

Hide URLs behind text for readability and conciseness.
2017-05-23 10:39:40 -04:00
Philipp Stephani
979107ec7a Improve fix for https://github.com/google/protobuf/issues/295
Requiring the legacy ‘cl’ library unconditionally pollutes the namespace.
Instead, require it only when compiling and in known-broken versions.

This is almost the same patch that opoplawski suggested, except that I removed
the test for ‘emacs-repository-version’, which isn’t defined in Emacs 24.3.
2017-05-23 15:27:29 +02:00
Dennis Cappendijk
3b227611d5 show help if protoc is called without any arguments, pre-empts -h and --help to show a useful message instead of just 'Missing input file.' 2017-05-22 16:21:48 +02:00
Thomas Van Lenten
8546620610 Merge pull request #3104 from thomasvl/ext_registry_copy
Fix ExtensionRegistry copying and add tests.
2017-05-17 15:05:20 -04:00
Thomas Van Lenten
49e4ba6098 Fix ExtensionRegistry copying and add tests.
- Fix up -copyWithZone: to not leave the two registries sharing
  some of the storage by using -addExtensions:.
- Improve -addExtensions: to clone the sub dict when there is
  nothing to merge into.
- A ExtensionRegistry unittests.
- Update project schemes to not have extra things in perf scheme.
2017-05-17 14:51:02 -04:00
Joshua Haberman
b28617b813 Merge pull request #2815 from devwout/ruby_json_emit_defaults
Ruby version optionally emits default values in JSON encoding.
2017-05-15 08:05:27 -07:00
Andreas Eger
78cb804063 change test for nanosecond accurate timestamps 2017-05-13 22:20:45 +02:00
Andreas Eger
ad203bcb2b fix floating point accuracy problem in Timestamp#to_f
`.quo` return the most exact devision which fixes accuracy problems for the
timestamp coercion
2017-05-13 21:38:15 +02:00
Łukasz Strzałkowski
82e50ba5c3 Workaround the docker bug when compiling artifacts
This is a workaround (https://github.com/moby/moby/issues/10180#issuecomment-190429512) the docker issue (https://github.com/moby/moby/issues/10180) which breaks protoc-artifacts build process with following error

```Rpmdb checksum is invalid: dCDPT(pkg checksums): devtoolset-1.1-elfutils.x86_64 0:0.154-6.el6 - u

The command '/bin/sh -c yum clean all && yum install -y devtoolset-1.1                    devtoolset-1.1-libstdc++-devel                    devtoolset-1.1-libstdc++-devel.i686' returned a non-zero code: 1```

https://github.com/moby/moby/issues/10180#issuecomment-190429512
2017-05-11 14:04:34 -07:00
Feng Xiao
455b61c6b0 Merge pull request #3062 from Oppen/master
Workaround gcc < 4.5.0 bug
2017-05-08 11:19:02 -07:00
Paul Yang
25abd7b7e7 Add compatibility test for php. (#3041)
* Add compatibility test for php.

* Revert API incompatible change.
2017-05-05 11:14:11 -07:00
Mario J. Rugiero
cd0efc0024 Workaround gcc < 4.5.0 bug
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=189

Signed-off-by: Mario J. Rugiero <mrugiero@gmail.com>
2017-05-05 14:02:49 -03:00
Adam Cozzette
483396068d Merge pull request #3043 from acozzette/javascript
Removed mention of Buffer in byteSourceToUint8Array
2017-05-04 12:21:14 -07:00
Adam Cozzette
f00e06c95b Removed mention of Buffer in byteSourceToUint8Array
The Closure compiler complains about Buffer since that class exists only
in Node. That logic does not seem to be needed (unit tests and conformance
tests pass without it), so let's just remove it to solve the problem.
2017-05-02 17:25:54 -07:00
Adam Cozzette
a64497c709 Merge pull request #2873 from myitcv/fix_1562
Javascript: use goog.crypt.byteArrayToString instead of String.fromCharCode.apply
2017-05-02 16:57:34 -07:00
Paul Jolly
bcb3506641 Fix #1562 by using goog.crypt.byteArrayToString instead of String.fromCharCode.apply 2017-05-02 13:40:42 +01:00
Adam Cozzette
2f4489a3e5 Merge pull request #3024 from acozzette/merge-3.3-to-master
Merged 3.3.x branch to master
2017-05-01 10:58:38 -07:00
makdharma
286f059842 added "objectivec" build target (#3033)
This target will be used by gRPC iOS bazel build system.
2017-05-01 09:49:26 -07:00
Adam Cozzette
9053033a50 Merge remote-tracking branch 'remotes/google/3.3.x' into merge-3.3-to-master 2017-04-27 14:55:53 -07:00
Adam Cozzette
067b1eec3b Merge pull request #3023 from acozzette/min
Fully qualify min as std::min in wire_format_lite.cc
2017-04-27 13:56:27 -07:00
Adam Cozzette
07c284f86c Fully qualify min as std::min in wire_format_lite.cc 2017-04-27 11:35:59 -07:00
Paul Yang
a6189acd18 Add prefix to enum value with reserved name. (#3020) 2017-04-26 16:32:21 -07:00
Adam Cozzette
cbd08cb7d1 Merge pull request #3018 from acozzette/using-namespace-std
Remove "using namespace std" from stubs/common.h
2017-04-26 13:56:24 -07:00
Feng Xiao
54d1701f6c Merge pull request #3015 from buchgr/unused-consts
Remove unused constants.
2017-04-26 11:09:42 -07:00
Adam Cozzette
7c76ac1735 Remove "using namespace std" from stubs/common.h
This prevents the contents of the std namespace from being effectively
pulled into the top-level namespace in all translation units that
include common.h. I left in individual using statements for a few common
things like std::set and std::map, because it did not seem worth going
through the churn of updating the whole codebase to fix those right now.
2017-04-26 08:25:01 -07:00
Paul Yang
3c0855e94a Add a test case for nested enum, which was missed previously. (#3010) 2017-04-25 10:47:09 -07:00
Jakob Buchgraber
b1c75bc742 Remove unused constants.
When compiling with -Werror, -Wunused-const-variable the build fails due
to those two constants not being used.
2017-04-25 12:49:00 +02:00
Feng Xiao
4920e27a48 Merge pull request #3008 from postmasters/patch-1
Add a link to dart-lang/protobuf
2017-04-24 13:09:48 -07:00
Paul Yang
fba2acd72e Add nested enum descriptor in php rumtime. (#3009) 2017-04-24 12:40:37 -07:00
Paul Yang
e64b618b21 Update php version number to 3.3.0 (#3001) 2017-04-24 09:24:43 -07:00
postmasters
4777574a6c Add a link to dart-lang/protobuf 2017-04-24 08:46:56 -07:00
Paul Yang
6fff091c49 Throw exception when parsing invalid data. (#3000) 2017-04-21 15:00:00 -07:00
Feng Xiao
f418b9e3eb Merge pull request #2996 from xfxyjwf/3.3.x
Fix python3 issue.
2017-04-20 17:32:48 -07:00
Paul Yang
4523c9c233 Allow proto files to import descriptor.proto (#2995)
descriptor.proto uses proto2 syntax, which is not ready for external
usage. However, some proto3 files import descriptor.proto and cannot be
used. In this PR, all references (We cheated by only removing
extensions, which is enough for now. User should avoid using messages
defined in descriptor.proto as field type.) to content in
descriptor.proto are removed from generated files. Those that import
descriptor.proto can be used like other proto files.
2017-04-20 16:55:56 -07:00
Feng Xiao
478119fe77 Fix python3 issue. 2017-04-20 16:30:26 -07:00
Feng Xiao
14afc3fd41 Merge pull request #2992 from xiaogaozi/patch-1
Add gogoprotobuf to third-party add-ons list
2017-04-20 11:12:02 -07:00
Changjian Gao
f85eecb585 Add gogoprotobuf to third-party add-ons list 2017-04-20 19:53:11 +08:00
Paul Yang
4c57e8475f Prepend "PB" to generated classes whose name are reserved words. (#2990) 2017-04-20 01:19:03 -07:00
Paul Yang
b97cd573e4 Add test for nested enum for php (#2989) 2017-04-19 21:20:55 -07:00
Paul Yang
7be088202b Enum defined without package have incorrect class name. (#2988)
Fix the bug by sharing the code for generating class name for both
message and enum.
2017-04-19 20:03:34 -07:00
Paul Yang
190b5270c8 Make PHP c extension work with PHP7 (#2951) 2017-04-19 16:23:51 -07:00
Feng Xiao
357afc39de Merge pull request #2508 from yliu120/pass_default_env_to_protoc
add a key to ctx.action dict to prevent protoc losing the default env
2017-04-19 11:28:54 -07:00
Feng Xiao
0a93f67055 Merge pull request #2987 from konsumer/patch-1
Add node-protoc-plugin to "Other Utilities"
2017-04-19 10:30:42 -07:00
Adam Cozzette
594f810081 Merge pull request #2982 from mda000/issue2972
Simplify the Element dtor invocation when freeing elements in InternalDeallocate
2017-04-19 08:34:54 -07:00
David Konsumer
3055a02125 Add node-protoc-plugin to "Other Utilities" 2017-04-18 18:58:21 -07:00
Thomas Van Lenten
a3873cafae Merge pull request #2985 from thomasvl/class_check_tweaks
Tighten up class usage/checks.
2017-04-18 13:28:41 -04:00
Thomas Van Lenten
f5a01d1bbd Tighten up class usage/checks.
- Ensure extensions resolution/wiring is happening directly on the
  messageClass (incase someone is doing odd things our out classes).
- Make the extension message check match the other class checks in
  for mergeFrom/isEqual/etc.
2017-04-18 13:10:52 -04:00
Michael Allen
2240a785f9 Simplify the Element dtor invocation when freeing elements in
InternalDeallocate to avoid confusing the compiler when there's
a class named Element already defined in the global namespace.
2017-04-17 10:59:31 -07:00
Feng Xiao
8aa927f08f Merge pull request #2950 from anuraaga/dev_rag
Allow unknown values for Map put*Value methods just like every other …
2017-04-12 10:42:18 -07:00
Feng Xiao
43234828da Merge pull request #2967 from xfxyjwf/3.3.x
Fix map serialization
2017-04-11 16:52:06 -07:00
Feng Xiao
5777259273 Cherry-pick cl/152450543 2017-04-11 16:15:46 -07:00
Feng Xiao
cad0258d17 Cherry-pick cl/151775298 2017-04-11 16:14:00 -07:00
Feng Xiao
fc3ea97870 Merge pull request #2955 from xfxyjwf/3.3.x
Add include for INT_MAX
2017-04-11 16:13:32 -07:00
Jie Luo
899460c9cb cherrypick descriptor_pool.FindFileContainingSymbol by extensions (#2962)
* Use PyUnicode_AsEncodedString() instead of PyUnicode_AsEncodedObject()

* Cherrypick the fix descriptor_pool.FindFileContainingSymbol by extensions.
2017-04-10 16:37:57 -07:00
Feng Xiao
bfeeb98517 Add include for INT_MAX 2017-04-08 00:39:03 +00:00
Feng Xiao
e91caa1f19 Merge pull request #2949 from xfxyjwf/3.3.x
Cleanup reflection objects for map entry.
2017-04-07 11:30:40 -07:00
Anuraag Agrawal
bf483dfb99 Allow unknown values for Map put*Value methods just like every other enum mutation method. 2017-04-07 14:50:52 +09:00
Feng Xiao
ee9c7f17e9 Cleanup reflection objects for map entry. 2017-04-06 16:47:18 -07:00
Adam Cozzette
efec757104 Merge pull request #2937 from anuraaga/dev_rag2
Fix duplicate fields test and Any test. The repeated version is passing because nu…
2017-04-06 16:27:54 -07:00
Feng Xiao
18c13c93de Merge pull request #2942 from xfxyjwf/3.3.x
Update version number and changelog for 3.3.0
2017-04-06 11:46:51 -07:00
Feng Xiao
21b0b3ca36 Update generated code. 2017-04-05 17:45:21 -07:00
Feng Xiao
80f0c0ac40 Update version number and changelog for 3.3.0 2017-04-05 17:32:17 -07:00
Jie Luo
69bfde22b6 Merge pull request #2922 from anandolee/master
Use PyUnicode_AsEncodedString() instead of PyUnicode_AsEncodedObject()
2017-04-05 16:34:54 -07:00
Anuraag Agrawal
09328db1ff Fix test for unexpected type url when parsing Any. Currently, the test fails since TestAllTypes doesn't have field '@type', which is the same test as testUnknownFields. 2017-04-05 17:44:26 +09:00
Adam Cozzette
139fd0a1c5 Merge pull request #2933 from mharrend/patch-1
Adding default shell env to allow non-default compilers
2017-04-04 09:34:06 -07:00
Adam Cozzette
37c7b766b3 Merge pull request #2930 from anuraaga/dev_rag
Fix error message for int64 parse failure.
2017-04-04 09:31:14 -07:00
Anuraag Agrawal
662f97841e Fix duplicate fields test. The repeated version is passing because null values in a repeated field are rejected and not testing what it wanted to. Also adds a oneof version that verifies the case of oneof fields of different names (currently only same name check seems to be tested).
Also fix spelling of a test.
2017-04-04 17:27:53 +09:00
Adam Cozzette
cc3fa2ec80 Merge pull request #2676 from acozzette/js-compatibility-tests
JS compatibility tests
2017-04-03 14:39:26 -07:00
Adam Cozzette
10ea25133d Added compatibility tests for version 3.0.0 2017-04-03 12:55:20 -07:00
Adam Cozzette
7e5f980508 Split test protos into two groups 2017-04-03 12:55:20 -07:00
Marco A. Harrendorf
dd04ffb923 Adding default shell env
I am adding default shell environment, so that protobuf compilation makes use of set
LD_LIBRARY_PATH and so on.
In this way, also non-default gcc installations (e.g. not in /usr/lib) can be used to compile protobuf.
This would fix the following issue:
https://github.com/bazelbuild/bazel/issues/2515
2017-04-03 17:01:36 +02:00
Anuraag Agrawal
58373fa160 Fix error message for int64 parse error. 2017-04-03 17:35:42 +09:00
Anuraag Agrawal
11c902ea2e Add IntelliJ project to gitignore for java project. 2017-04-03 17:32:08 +09:00
Feng Xiao
bd74319107 Update Java conformance failure list. 2017-03-31 15:59:48 -07:00
Feng Xiao
32ad5a3e0d Use "git reset --hard" to actually reset the code. 2017-03-31 14:04:29 -07:00
Feng Xiao
b7c813fb67 Update jenkins Java dependencies. 2017-03-31 11:13:28 -07:00
Feng Xiao
c2b3b3e04e Update Java version number and dependency. 2017-03-30 18:25:11 -07:00
Feng Xiao
624d44f042 Update objective-c conformance failure list. 2017-03-30 17:45:14 -07:00
Feng Xiao
d5827784cf Fix C++ distcheck. 2017-03-30 17:43:45 -07:00
Feng Xiao
fe97d79abf Fix MSVC DLL build. 2017-03-30 23:54:39 +00:00
Feng Xiao
fab8812cc1 Update python conformance failure list. 2017-03-30 16:05:25 -07:00
Feng Xiao
c52e54f62b Update jenkins Java maven dependencies. 2017-03-30 15:57:18 -07:00
Feng Xiao
057a2851e4 Update C# conformance failure list. 2017-03-29 16:19:00 -07:00
Feng Xiao
e47c068cfa Update python conformance failure list. 2017-03-29 16:17:18 -07:00
Feng Xiao
84f6954ca9 Fix Java build. 2017-03-29 16:03:53 -07:00
Jie Luo
c348d46a9b Use PyUnicode_AsEncodedString() instead of PyUnicode_AsEncodedObject() 2017-03-29 15:54:06 -07:00
Feng Xiao
acde1651b5 Update BUILD file for C# tests. 2017-03-29 15:14:18 -07:00
Feng Xiao
32d7830e4b Fix C++ build for down-integration. 2017-03-29 14:52:33 -07:00
Feng Xiao
d36c0c538a Down-integrate from google3. 2017-03-29 14:33:05 -07:00
Juan David Dominguez
4a0dd03e52 Removes ignored const from return type (#2915)
See https://github.com/google/protobuf/issues/2425
2017-03-29 11:39:29 -07:00
Thomas Van Lenten
258406b88f Merge pull request #2919 from thomasvl/drop_dispatch
Remove the use of dispatch_once that is heap backed.
2017-03-29 14:07:07 -04:00
Thomas Van Lenten
130c166697 Remove the use of dispatch_once that is heap backed.
Apple recently updated the docs on dispatch_once to point out
that the storage for the dispatch_once_t must be static or global,
but not something that was ever used before as the implementation
doesn't use a memory barrier.  So we drop the use and create the
semaphore when needed and use an atomic swap deal with any
threading races.
2017-03-29 13:03:33 -04:00
Thomas Van Lenten
ba3fa41ba8 Merge pull request #2918 from thomasvl/xcode_8_3
Add support for Xcode 8.3 to the build helper.
2017-03-29 11:03:30 -04:00
Thomas Van Lenten
558ba98811 Add support for Xcode 8.3 to the build helper. 2017-03-29 11:02:51 -04:00
Thomas Van Lenten
04c77c4e4b Merge pull request #2913 from thomasvl/conformance_ignores
Add some new ignores for things generated in conformance.
2017-03-29 09:44:59 -04:00
drivehappy
d43eaf2b8f Fix gcc warning when using map (#2213)
* Issue #2211: Addressing GCC warning on enumeral/non-enumeral in conditional expression.

* Updated per 80 character wrap.
2017-03-28 16:57:19 -07:00
Adam Cozzette
585993201a Merge pull request #2914 from acozzette/nacl
Added a workaround to allow building for NaCl
2017-03-28 13:54:50 -07:00
Adam Cozzette
f316375a95 Added a workaround to allow building for NaCl
arm-nacl-clang seems to produce a mysterious compiler error when it
encounters __builtin_clzll, so when we are building for NaCl, let's
avoid that in favor of the portable implementation of
Log2FloorNonZero64.
2017-03-28 09:45:14 -07:00
Thomas Van Lenten
8adf57e0fa Add some new ignores for things generated in conformance. 2017-03-28 11:04:58 -04:00
Thomas Van Lenten
b3f3e123aa Merge pull request #2912 from thomasvl/objc_recursion_limit
Raise the recursion limit to 100 to match other languages.
2017-03-28 09:18:14 -04:00
Thomas Van Lenten
ddb438855a Raise the recursion limit to 100 to match other languages. 2017-03-28 09:10:20 -04:00
Joshua Haberman
d9e0119f2c Merge pull request #2858 from haberman/gopackage
Changed go_package for plugin.proto.
2017-03-27 12:04:08 -07:00
Joshua Haberman
c565e25c7d Merge pull request #1662 from haberman/jsconformance
Conformance tests for JavaScript (Node.js). 15 tests are failing.
2017-03-27 12:03:09 -07:00
Jie Luo
7610f101e8 Merge pull request #2884 from anandolee/master
Add FormatEnumsAsIntegers support for Json Format. Scale JsonFormatter.Settings for multi options.
2017-03-27 11:05:38 -07:00
Jie Luo
689e4bf5f4 Add FormatEnumAsInt support for Json Format. And scale JsonFormatter.Settings to multiple options. 2017-03-24 12:05:52 -07:00
Feng Xiao
373809e5f5 Merge pull request #2897 from cgrushko/patch-5
Compile the Java proto runtime with Java 6
2017-03-22 13:35:52 -07:00
cgrushko
6f21e29268 Compile the Java proto runtime with Java 6
in order to avoid errors related to generics when 
building user code in newer versions of Java.
2017-03-22 14:27:51 -04:00
Paul Yang
1387a6795c Update commit number in Docker to update composer dependency (#2869) 2017-03-21 10:18:49 -07:00
Adam Cozzette
ffa932bf10 Merge pull request #2861 from byronyi/#710
migrate delimited messages functions to util package
2017-03-20 13:02:40 -07:00
Bairen Yi
312e2dbcfb Update BUILD 2017-03-21 03:52:37 +08:00
Feng Xiao
db3ef48ede Merge pull request #2860 from prehistoric-penguin/master
Remove duplicated copyright statement
2017-03-20 10:49:48 -07:00
Adam Cozzette
20181f6a1a Merge pull request #2854 from hesmar/attributesFix
fix attributes warning
2017-03-20 09:51:31 -07:00
Adam Cozzette
4d273f28dc Merge pull request #2870 from acozzette/memcpy-memmove
Ruby: only link against specific version of memcpy if we're using glibc
2017-03-20 08:26:06 -07:00
Feng Xiao
15b60bccf8 Merge pull request #2867 from mojoBrendan/master
Add preserve_proto_field_names option to JsonPrintOptions
2017-03-17 15:05:58 -07:00
Adam Cozzette
ea5ef14aa0 Ruby: only link against specific version of memcpy if we're using glibc
We have some special code in wrap_memcpy.c to ensure that we use the
2.2.5 version of memcpy, for compatibility with older versions of glibc.
However, we need to make sure we only attempt to do this when we are
actually building with glibc, so that the code can also build
successfully against other libc implementations such as musl.
2017-03-17 11:23:01 -07:00
Jie Luo
c12cc3490b Merge pull request #2837 from anandolee/master
DefaultValueObjectWriter should populate oneof message field
2017-03-17 11:10:24 -07:00
Paul Yang
6b27c1f981 Add file option php_class_prefix (#2849)
This option will be prepended to generated classes of all messages in
the containing file.
2017-03-17 11:08:06 -07:00
Feng Xiao
c0871aa49c Merge pull request #2848 from xfxyjwf/freebsd
Fix freebsd build.
2017-03-17 10:42:20 -07:00
Bairen Yi
e8e6aa2864 Update delimited_message_util_test.cc 2017-03-18 00:32:43 +08:00
Brendan McCarthy
89eb4e51b2 Add option to preserve original proto field names 2017-03-17 22:47:38 +10:00
Ewout
aec0711075 Ruby tests compare parsed JSON instead of raw JSON 2017-03-17 10:28:17 +01:00
Brendan McCarthy
1eee3202fc Add use_snake_case_for_field_names option to JsonPrintOptions 2017-03-17 18:46:18 +10:00
Byron Yi
c415a1445b fix several issues 2017-03-17 10:00:59 +08:00
Feng Xiao
44dc55587e Merge pull request #2866 from xfxyjwf/nano
Add a notice for nano.
2017-03-16 16:47:10 -07:00
Feng Xiao
ddc00963c0 Add a notice for nano.
We no longer supports nano and recommend protobuf lite over nano for
Android users.
2017-03-16 16:09:41 -07:00
Josh Haberman
1b0db1cb83 Removed obsolete comments and added docs. 2017-03-16 15:19:09 -07:00
Josh Haberman
0df20284d0 Properly regenerated descriptor.proto. 2017-03-16 15:07:22 -07:00
Joshua Haberman
89c3c456d2 Merge pull request #2859 from haberman/junit-dep-scope
Changed scope of Java deps to "test".
2017-03-16 12:25:42 -07:00
Joshua Haberman
2957703a01 Merge pull request #2847 from haberman/ruby-toh
Ruby: fixed Message#to_h for map fields.
2017-03-16 09:28:09 -07:00
Adam Cozzette
0fad0e138f Merge pull request #2794 from acozzette/jspb-extensions
JS: ensure that extension values are serialized even if they're falsy
2017-03-16 09:23:32 -07:00
Byron Yi
acaa9407e3 add delimited_message_util.cc to libprotobuf.cmake 2017-03-16 20:52:58 +08:00
Byron Yi
7008a88e2b add LIBPROTOBUF_EXPORT to make msvc happy 2017-03-16 20:35:35 +08:00
Byron Yi
cb3e84b78e migrate delimited messages functions to util package 2017-03-16 20:01:22 +08:00
prehistoric-penguin
33cc25f36c Remove duplicated copyright statement 2017-03-16 11:23:07 +08:00
Josh Haberman
496cd481fa Changed scope of Java deps to "test".
This is per: https://github.com/google/protobuf/issues/2019
2017-03-15 18:27:05 -07:00
Josh Haberman
e62e30c309 Changed go_package for plugin.proto.
For more info see: https://github.com/google/protobuf/issues/1289
2017-03-15 17:48:46 -07:00
Joshua Haberman
4842363ee6 Merge pull request #2023 from odeke-em/fix-print-help-to-stdout
compiler/cli: PrintHelpText prints to stdout instead of stderr
2017-03-15 14:45:03 -07:00
Adam Cozzette
e77a09e1e9 Incremented Ruby version number to 3.2.0.1 2017-03-15 14:16:49 -07:00
Josh Haberman
8c40b5149a Ruby: update Gemspec. 2017-03-15 14:16:49 -07:00
Konstantin Podsvirov
97cbc42621 Fix libprotoc.cmake to generate well_known_types_embed.cc
Unfortunate typo. Just one extra ',' symbol, has led to the hidden implicit behavior.

Now everything will be fine.
2017-03-15 14:16:49 -07:00
Paul Yang
f23869c615 Bug fix: When encoding, negative int32 values should be padded to int64 (#2660)
in order to be wire compatible.
2017-03-15 14:16:49 -07:00
Josh Haberman
014a5507fb Ruby: build packages for Ruby 2.4. 2017-03-15 14:16:49 -07:00
Adam Cozzette
c57c77b4b7 Merge pull request #2829 from afrantzis/hide-unnecessary-library-symbols
Hide unnecessary exported library symbols
2017-03-15 11:41:14 -07:00
Josh Haberman
324a299a55 Made formatting more consistent. 2017-03-15 10:35:15 -07:00
Adam Cozzette
ed0ef54045 Merge pull request #2846 from acozzette/bytestream-comment
Updated an outdated comment in bytestream.h
2017-03-15 09:13:44 -07:00
Thomas Van Lenten
d18df81488 Merge pull request #2855 from thomasvl/copy_note
Document deep copy in the header
2017-03-15 11:07:05 -04:00
Thomas Van Lenten
5e4f14fae4 Document deep copy in the header 2017-03-15 10:50:31 -04:00
Markus Heß
b4b855cde4 fix attributes warning 2017-03-15 15:20:54 +01:00
Feng Xiao
416f90939d Fix freebsd build.
It turns out system headers included by generated plugin.pb.h file already contains
major/minor macro definitions when built on FreeBSD and we need to add #undefs to
the generated header file.

This change also fixes another compile error regarding EXPECT_DEATH on FreeBSD.
2017-03-14 23:41:54 +00:00
Josh Haberman
9c6b8cb9bf Ruby: fixed Message#to_h for map fields. 2017-03-14 14:27:16 -07:00
Josh Haberman
95b4427d39 Build system fixes for JS conformance tests. 2017-03-14 12:45:57 -07:00
Joshua Haberman
43f2db776c Merge pull request #2843 from haberman/check
Replace CHECK() with GOOGLE_CHECK().
2017-03-14 12:10:23 -07:00
Adam Cozzette
746ca59885 Updated an outdated comment in bytestream.h 2017-03-14 10:08:36 -07:00
Josh Haberman
874e382fde Replace CHECK() with GOOGLE_CHECK().
Fixes: https://github.com/google/protobuf/issues/1175
2017-03-13 16:07:42 -07:00
Josh Haberman
8df69f0894 Conformance test for JS now work, though 15 tests fail. 2017-03-13 15:10:53 -07:00
Feng Xiao
f0a5c1033a Merge pull request #2836 from xfxyjwf/i894
Double-quote file paths in extract_includes.bat.in
2017-03-13 15:03:50 -07:00
Jisi Liu
ddfc86b1f7 Merge pull request #2835 from pherl/javaep
Suppress the last unchecked warning.
2017-03-13 10:56:20 -07:00
Alexandros Frantzis
13d165de9e Hide unnecessary exported library symbols 2017-03-13 14:27:39 +02:00
Jie Luo
d59592af61 DefaultValueObjectWriter should populate oneof message field 2017-03-10 16:58:20 -08:00
Feng Xiao
c94555f955 Double-quote file paths in extract_includes.bat.in
This allows the file path to contain spaces which is very common on
windows.
2017-03-10 16:32:19 -08:00
Jisi Liu
f4f31e73f2 Suppress the last unchecked warning.
Likely to be java language issue. Varargs are considered arrays, thus
using generic with varargs will cause unchecked warning about generic
array creation.
2017-03-10 15:33:17 -08:00
Jie Luo
a69bc9de75 Merge pull request #2822 from anandolee/master
Detect generated code of WKT, addressbook and conformance protos
2017-03-10 15:24:51 -08:00
Jisi Liu
f54fb9d729 Merge pull request #2832 from pherl/javaep
Fix java code according to error prone.
2017-03-10 15:19:04 -08:00
Feng Xiao
e11cd3ee6e Merge pull request #2818 from xfxyjwf/i1470
Don't expose gson exceptions in JsonFormat.
2017-03-10 15:08:51 -08:00
Feng Xiao
92064a40ce Merge pull request #2824 from xfxyjwf/i1415
Use per-type table to lookup JSON name.
2017-03-10 15:03:29 -08:00
Feng Xiao
cd6eb91684 Merge pull request #2826 from xfxyjwf/i1374
Add missing thread dependency in cmake.
2017-03-10 15:03:15 -08:00
Feng Xiao
81f4fe5aab Merge pull request #2827 from xfxyjwf/i1251
Update comments for setSizeLimit.
2017-03-10 15:02:52 -08:00
Jisi Liu
81fe52fbd4 Fix java code according to error prone. 2017-03-10 14:53:15 -08:00
Paul Yang
616e68ecc1 Repeated/Map field setter should accept a regular PHP array (#2817)
Accept regular PHP array for repeated/map setter. Existing map/repeated
field will be swapped by a clean map/repeated field. Then, elements in
the array will be added to the map/repeated field. All elements will be
type checked before adding.

See #2686 for detail.
2017-03-10 13:42:59 -08:00
Jie Luo
ae220cda61 Add auto detect for generated code of WKT protos, addressbook.proto and conformance.proto 2017-03-10 10:44:20 -08:00
Feng Xiao
03c8c8be6d Update comments for setSizeLimit. 2017-03-09 17:24:42 -08:00
Jisi Liu
a1bb147e96 Merge pull request #2825 from pherl/javawarning
Cherry-pick changes from javalite branch to also fix Java warnings in the master branch
2017-03-09 17:13:55 -08:00
Feng Xiao
1ece7c09af Add missing thread dependency in cmake. 2017-03-09 17:02:17 -08:00
Jisi Liu
009e491bd7 Fix GeneratedMessageV3 warnings. 2017-03-09 16:56:18 -08:00
Feng Xiao
da003550e8 Merge pull request #2809 from xfxyjwf/i2464
Make JsonFormat locale independent.
2017-03-09 16:38:59 -08:00
Feng Xiao
61e87f3d41 Use per-type table to lookup JSON name.
Different fields from different messages can map to the same JSON name
and the original global lookup table is only capable of mapping one of
such fields. This change converts the global table to per-type tables
so fields from different messages won't conflict.
2017-03-09 16:30:15 -08:00
Jisi Liu
7c7534413a Fix lint warnings in the javalite branch. 2017-03-09 16:26:55 -08:00
Joshua Haberman
cad6a51a30 Merge pull request #2819 from haberman/pythonexcept
update_failure_list.py: fixed Python "raise" statement.
2017-03-09 14:58:01 -08:00
Josh Haberman
3e6245e5d7 update_failure_list.py: fixed Python "raise" statement. 2017-03-09 14:48:28 -08:00
Feng Xiao
075475f834 Don't expose gson exceptions in JsonFormat. 2017-03-09 14:42:45 -08:00
Adam Cozzette
bbfb9d52da Merge pull request #2804 from acozzette/ruby-memcpy
Ruby: wrap calls to memcpy so that gem is compatible with pre-2.14 glibc
2017-03-09 14:30:50 -08:00
Feng Xiao
8e465dcf46 Merge pull request #2810 from xfxyjwf/i1994
Avoid redundant type casts for oneof bytes fields.
2017-03-09 13:57:34 -08:00
Feng Xiao
af2d5f5ad3 Merge pull request #2775 from xfxyjwf/fixmajor
Undef major/minor if they are defined as macro.
2017-03-09 13:50:31 -08:00
Jisi Liu
9afacb44a3 Merge pull request #2814 from pherl/javadeprecate
Add annotations for deprecated messages in Java
2017-03-09 13:50:19 -08:00
Jisi Liu
baceff7c9c Add annotations for deprecated messages in Java 2017-03-09 11:51:58 -08:00
Ewout
008dc92c9d Ruby version optionally emits default values in JSON encoding.
Usage: Message.encode_json(m, emit_defaults: true)
Message fields that are nil will still not appear in the encoded JSON.
2017-03-09 20:47:56 +01:00
Adam Cozzette
9fa40314fc Ruby: wrap calls to memcpy so that gem is compatible with pre-2.14 glibc
This commit adds a __wrap_memcpy function and a linker flag to use that
in place of memcpy for our Ruby gem C extension. This allows us to
always use the 2.2.5 version of memcpy, making it possible to use the
gem on distributions with pre-2.14 versions of glibc.

Before this change:
$ objdump -T protobuf_c.so | grep memcpy
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3.4 __memcpy_chk
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.14  memcpy

After:
$ objdump -T protobuf_c.so | grep memcpy
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 memcpy
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3.4 __memcpy_chk
0000000000042450 g    DF .text  0000000000000005  Base __wrap_memcpy

This is based on gRPC's solution to a similar problem:
5098508d2d/src/core/lib/support/wrap_memcpy.c

This fixes issue #2783.
2017-03-09 10:03:22 -08:00
Feng Xiao
c31154316b Avoid redundant type casts for oneof bytes fields. 2017-03-08 17:34:38 -08:00
Feng Xiao
4ae8656b6d Make JsonFormat locale independent. 2017-03-08 16:56:43 -08:00
Feng Xiao
fa1788026c Merge pull request #2602 from GreatFruitOmsk/issue-2428
Method Builder#clone() has been changed to bypass Java 1.6 compiler issue.
2017-03-08 15:28:34 -08:00
Jie Luo
920af75d1c Fix Bad Link for Common Lisp 2017-03-08 15:24:04 -08:00
Paul Yang
dd8d5f57d7 Rename encode/decode to serializeToString/mergeFromString (#2795)
This better shows the semantic of the API. For already setted fields,
mergeFromString do replacement for singular fields and appending for
repeated fields.
2017-03-08 14:31:34 -08:00
Emmanuel Odeke
769b693564
compiler/cli: PrintHelpText prints to stdout instead of stderr
Fixes #698.

PrintHelpText now prints to standard output instead of to standard error.
The purpose of this CL is to make it easy for users to grep for matches
otherwise stderr output has to be awkwardly redirectly to stdout
using this shell trick  `2>&1`, for example
```shell
protoc --help 2>&1 | grep cpp
```

of which we shouldn't be making users have to work that hard just to
get use of --help.

+ Exhibits:
* Before:
```shell
$ protoc --help | grep cpp
Usage: protoc [OPTION] PROTO_FILES
Parse PROTO_FILES and generate output based on the options given:
  -IPATH, --proto_path=PATH   Specify the directory in which to search
for
                              imports.  May be specified multiple times;
                              directories will be searched in order.  If
not
                              given, the current working directory is
used.
  --version                   Show version info and exit.
  -h, --help                  Show this text and exit.
  --encode=MESSAGE_TYPE       Read a text-format message of the given
type
                              from standard input and write it in binary
                              to standard output.  The message type must
                              be defined in PROTO_FILES or their
imports.
  --decode=MESSAGE_TYPE       Read a binary message of the given type
from
                              standard input and write it in text format
                              to standard output.  The message type must
                              be defined in PROTO_FILES or their
imports.
  --decode_raw                Read an arbitrary protocol message from
                              standard input and write the raw tag/value
                              pairs in text format to standard output.
No
                              PROTO_FILES should be given when using
this
                              flag.
  -oFILE,                     Writes a FileDescriptorSet (a protocol
buffer,
    --descriptor_set_out=FILE defined in descriptor.proto) containing
all of
                              the input files to FILE.
  --include_imports           When using --descriptor_set_out, also
include
                              all dependencies of the input files in the
                              set, so that the set is self-contained.
  --include_source_info       When using --descriptor_set_out, do not
strip
                              SourceCodeInfo from the
FileDescriptorProto.
                              This results in vastly larger descriptors
that
                              include information about the original
                              location of each decl in the source file
as
                              well as surrounding comments.
  --dependency_out=FILE       Write a dependency output file in the
format
                              expected by make. This writes the
transitive
                              set of input file paths to FILE
  --error_format=FORMAT       Set the format in which to print errors.
                              FORMAT may be 'gcc' (the default) or
'msvs'
                              (Microsoft Visual Studio format).
  --print_free_field_numbers  Print the free field numbers of the
messages
                              defined in the given proto files. Groups
share
                              the same field number space with the
parent
                              message. Extension ranges are counted as
                              occupied fields numbers.

  --plugin=EXECUTABLE         Specifies a plugin executable to use.
                              Normally, protoc searches the PATH for
                              plugins, but you may specify additional
                              executables not in the path using this
flag.
                              Additionally, EXECUTABLE may be of the
form
                              NAME=PATH, in which case the given plugin
name
                              is mapped to the given executable even if
                              the executable's own name differs.
  --cpp_out=OUT_DIR           Generate C++ header and source.
  --csharp_out=OUT_DIR        Generate C# source file.
  --java_out=OUT_DIR          Generate Java source file.
  --javanano_out=OUT_DIR      Generate Java Nano source file.
  --js_out=OUT_DIR            Generate JavaScript source.
  --objc_out=OUT_DIR          Generate Objective C header and source.
  --python_out=OUT_DIR        Generate Python source file.
  --ruby_out=OUT_DIR          Generate Ruby source file.
```

* After:
```shell
$ protoc --help | grep cpp
  --plugin=EXECUTABLE         Specifies a plugin executable to use.
                              Normally, protoc searches the PATH for
                              plugins, but you may specify additional
                              executables not in the path using this
flag.
                              Additionally, EXECUTABLE may be of the
form
                              NAME=PATH, in which case the given plugin
name
                              is mapped to the given executable even if
                              the executable's own name differs.
  --cpp_out=OUT_DIR           Generate C++ header and source.
  --csharp_out=OUT_DIR        Generate C# source file.
  --java_out=OUT_DIR          Generate Java source file.
  --javanano_out=OUT_DIR      Generate Java Nano source file.
  --js_out=OUT_DIR            Generate JavaScript source.
  --objc_out=OUT_DIR          Generate Objective C header and source.
  --python_out=OUT_DIR        Generate Python source file.
  --ruby_out=OUT_DIR          Generate Ruby source file.
```
2017-03-08 11:42:11 -07:00
Feng Xiao
2b7430d96a Merge pull request #2793 from keveman/master
Removed a stray return statement, causing compilation error.
2017-03-07 14:22:57 -08:00
Jisi Liu
f6d8c83384 Merge pull request #2613 from aausch/fix_memory_leak
optimization and quick workaround to memory leak
2017-03-06 16:48:54 -08:00
Manjunath Kudlur
21b58b51fe Removed a stray return statement, causing compilation error. 2017-03-06 15:50:26 -08:00
Adam Cozzette
651ba62ab5 JS: ensure that extension values are serialized even if they're falsy
There was a bug where for JavaScript we would only serialize an
extension value if it evaluated as truthy, which meant that values like
0 would get silently dropped (even in proto2, where field presence is
significant). This fixes issue #2605, and takes care of the output of
toObject() in addition to the binary format.
2017-03-06 15:37:40 -08:00
Jie Luo
06f9f609e1 Detect if Descriptor.cs changes for csharp
Merge pull request #2788 from anandolee/master
2017-03-06 15:33:41 -08:00
Josh Haberman
f873d3213c Added JavaScript conformance tests. All tests pass! 2017-03-06 10:42:27 -08:00
Josh Haberman
27b1f2b477 WIP. 2017-03-06 10:42:27 -08:00
Feng Xiao
0c0a8879c3 Merge pull request #2751 from keveman/master
Added a header only cc_library target for the protobuf library.
2017-03-06 10:41:19 -08:00
Adam Cozzette
008ff033ef Merge pull request #2784 from acozzette/log-2-floor-int
Return uint32 from Log2FloorNonZero64
2017-03-03 07:06:15 -08:00
Manjunath Kudlur
6837b2dcb7 Added comment explaining the protobuf_headers target. 2017-03-02 18:02:05 -08:00
Jie Luo
af13bff3c7 Detect if Descriptor.cs changes for csharp 2017-03-02 17:15:58 -08:00
Feng Xiao
8610d0a9dd Merge pull request #2755 from xfxyjwf/rubycomp
Add Ruby compatibilty test against 3.0.0.
2017-03-02 14:33:02 -08:00
Thomas Van Lenten
352526c214 Merge pull request #2785 from thomasvl/threading_race
Handing threading race resolving methods.
2017-03-02 17:14:52 -05:00
Thomas Van Lenten
2d1c5e26cb Handing threading race resolving methods.
- Don't prune the extension registry as that can lead to failures when two
  threads are racing.
- If adding the method fails, check and see if it already is bound to decide
  the return result. Deals with threading races binding the methods.
2017-03-02 16:34:11 -05:00
Adam Cozzette
938206d66c Return uint32 from Log2FloorNonZero64
A uint32 is big enough to hold any return value from that function, and
doing it this way prevents compiler warnings in coded_stream.h about
narrowing a uint64 to a uint32.
2017-03-02 11:31:38 -08:00
Adam Cozzette
a7e3b0ab01 Merge pull request #2774 from acozzette/closure-builder
Use closurebuilder.py in favor of calcdeps.py for compiling JavaScript
2017-03-02 08:47:20 -08:00
Sergio Campamá
8b182cc455 Disable static analyzer for message semaphore creation (#2748)
Disable static analyzer for message semaphore creation
2017-03-01 14:00:56 -05:00
Matt Hauck
6011d7ca4c Fix gcc 4.1 build (#1035) (#1913)
* Fix gcc 4.1.2 compilation of map_field_inl.h

Fixes "error: object missing in reference to '...'" errors from #1035

* Disable 64-bit map keys on gcc <= 4.1

* Add missing case statements
2017-03-01 10:45:43 -08:00
Matt Hauck
25ecd559cc Change hint type to const void* (#2568)
This is both more correct, and the build fails on AIX without it
2017-03-01 10:43:28 -08:00
Paul Yang
bcbaabe53a Add mergeFrom method on Message (#2766)
This method merges the contents of the specified message into the
current message. Singular fields that are set in the specified message
overwrite the corresponding fields in the current message.  Repeated
fields are appended. Map fields key-value pairs are overritten.
Singular/Oneof sub-messages are recursively merged. All overritten
sub-messages are deep-copied.
2017-03-01 10:39:48 -08:00
Adam Cozzette
671e075c5e Use closurebuilder.py in favor of calcdeps.py for compiling JavaScript
There are two motivations for this:
1) calcdeps.py is deprecated and replaced by closurebuilder.py.
2) As part of this I was able to tweak things so that the Closure
compiler does not attempt to examine every .js file in the tree under
js/. This makes it possible to put compatibility tests and related files
in a subdirectory without them getting mixed up with the main .js files
we care about.
2017-03-01 07:43:11 -08:00
Adam Cozzette
7339fc04c4 Merge pull request #2674 from acozzette/js-test-cleanup
Removed log statement from writer_test.js
2017-03-01 07:11:33 -08:00
Feng Xiao
b7f25d42d3 Undef major/minor if they are defined as macro. 2017-02-28 18:13:04 -08:00
Adam Cozzette
aff9d9d39c Removed log statement from writer_test.js
This tweak makes the test output a bit easier to read because it cuts
out a lot of unnecessary logging.
2017-02-28 13:49:56 -08:00
Jisi Liu
5274d6ee31 Merge pull request #2770 from xfxyjwf/fixcmake
Remove the use of C++11 features.
2017-02-28 10:57:41 -08:00
Feng Xiao
83b0cc9ba6 Merge pull request #2772 from sschuberth/master
Fix links to the license in meta-data
2017-02-28 10:52:02 -08:00
Jie Luo
606cb7ed2c There might be duplicated enum values when allow_alias is true. Add PreferredAlias into OriginalNameAttribute to remove the duplication (#2727) 2017-02-28 10:51:19 -08:00
Sebastian Schuberth
902af0816e Prefer the term "3-Clause BSD License" over "New BSD License"
The first is the newer name, which is also more telling.
2017-02-28 09:58:24 +01:00
Sebastian Schuberth
6395a1cbd9 Fix links to the New BSD License in meta-data
The "New BSD License" is the "3-Clause BSD License", but the links were
pointing to the "2-Clause BSD License".
2017-02-28 09:54:21 +01:00
Feng Xiao
ffde972ac7 Remove the use of C++11 features. 2017-02-27 18:01:07 -08:00
Feng Xiao
9118ad659b Add Ruby compatibilty test against 3.0.0. 2017-02-27 17:38:54 -08:00
Adam Cozzette
d41c47fff9 Merge pull request #2733 from wmamrak/patch-1
Disable MSVC warning C4309
2017-02-27 08:50:32 -08:00
Adam Cozzette
8d61f9c3bf Merge pull request #2729 from MarcelRaad/fix_inline_msvc12
Fix unresolved symbols with MSVC12 and /Zc:inline
2017-02-27 08:29:10 -08:00
Feng Xiao
b4b0e304be Merge pull request #2355 from xfxyjwf/fixjson
Speed up JSON parsing.
2017-02-24 15:41:09 -08:00
Adam Cozzette
8387b88cdc Merge pull request #2732 from AsturaPhoenix/master
const FieldDescriptorCompare
2017-02-24 14:44:17 -08:00
Adam Cozzette
66c64e7045 Merge pull request #2747 from liutikas/master
Fix unused variables warnings in generated_message_reflection.h
2017-02-24 14:43:14 -08:00
Adam Cozzette
8c8b8e61f2 Merge pull request #2734 from msabramo/patch-1
README.md: Make docs URL a link
2017-02-24 14:24:02 -08:00
Jisi Liu
72b82e6875 Merge pull request #2630 from blodan/master
FreeBSD compatibility
2017-02-24 12:52:53 -08:00
Thomas Van Lenten
963473b1dd Merge pull request #2753 from thomasvl/recursive_drop
Add GPBMessageDropUnknownFieldsRecursively() and tests.
2017-02-23 15:18:17 -05:00
Thomas Van Lenten
d07176654b Add GPBMessageDropUnknownFieldsRecursively() and tests.
GPBMessageDropUnknownFieldsRecursively() is a new helper to drop the
unknownFields from a message and all sub messages (in fields or extensions).
2017-02-23 15:04:06 -05:00
Manjunath Kudlur
2d430f8c72 Added a header only cc_library target for the protobuf library. 2017-02-23 08:17:24 -08:00
John Brock
17174b54dd Updating README
- Adding more detail on running tests
- Adding info about the status of .NET 3.5 support and how to enable .NET 3.5
2017-02-23 10:51:52 +00:00
John Brock
f83d129555 Upgrading test-related libraries
NUnit 3.4.0 —> 3.6.0
dotnet-test-nunit 3.4.0-alpha-2 —> 3.4.0-beta-3
2017-02-23 10:51:52 +00:00
John Brock
c9b2c8f327 Fixes for .NET 3.5 compatibility
* Changing DOTNET35 framework symbols in preprocessor directives to the default built-in value of NET35.
* Adding extension method StreamExtension.CopyTo for .NET 3.5 because it didn’t exist until .NET 4, and adding associated unit tests.
2017-02-23 10:51:52 +00:00
Aurimas Liutikas
a434bfc232 Fix compiler warnings about unused variables in generated_message_reflection.h 2017-02-22 14:14:13 -08:00
Feng Xiao
1a8cbfd355 Merge pull request #2736 from na-ka-na/master3
Add an option to always print enums as ints in Json API
2017-02-21 11:08:05 -08:00
Sanchay Harneja
172e0a6423 Add an option to always print enums as ints in Json API
https://github.com/google/protobuf/issues/2735
2017-02-18 17:06:43 -08:00
Marc Abramowitz
86208c526b README.md: Make docs URL a link
Dedent URL so it renders as a link and not as code (fixed width font and not clickable).
2017-02-18 13:05:19 -08:00
Wojciech Mamrak
37bd5d525b Disable MSVC warning C4309
> warning C4309: static_cast': truncation of constant value

introduced in commit 9db5b11c9c
2017-02-18 15:44:29 +01:00
Ross Wang
01a05a53f4 const FieldDescriptorCompare
Clang now validates that <set> comparators must have a const operator():
https://reviews.llvm.org/rL291969

Discussion:
https://groups.google.com/d/msg/protobuf/9W6zFIHaJ-4/9RrfwelpEQAJ
2017-02-17 15:48:08 -08:00
Marcel Raad
8f9c0a44bd
Fix unresolved symbols with MSVC12 and /Zc:inline
In #726 and #813, linking errors with MSVC14 were resolved. The change in
MSVC12 leading to these errors was not a newly introduced bug, but that
/Zc:inline was made on by default. This option is also available with MSVC12,
so the workaround should be applied for it too.
2017-02-17 12:13:08 +01:00
Adam Cozzette
a9ab38c171 Merge pull request #2722 from ckennelly/unified
Merge #2653, #2622, #2579, #2652
2017-02-16 13:42:17 -08:00
Chris Kennelly
8af35f28f6 Keep loop bounds in a local variable for string fields. 2017-02-15 11:41:46 -08:00
Chris Kennelly
a6c30d9705 Keep loop bounds in a local variable. 2017-02-15 11:40:27 -08:00
Chris Kennelly
9db5b11c9c Work with truncated tag numbers.
This allows more compact comparisons (1 byte instead of 4 byte
immediates on x86) for each possible wire/tag inside each field.
2017-02-15 11:39:39 -08:00
Chris Kennelly
0026dff9f6 Expose rvalue setters for repeated string fields.
rvalue setters for scalar string fields were added in #2506.
2017-02-15 11:35:24 -08:00
Adam Cozzette
38b14408c5 Merge pull request #2663 from ckennelly/varint-size
Inline branch-less VarintSize32/VarintSize64 implementations.
2017-02-15 10:44:58 -08:00
Adam Cozzette
15360e59cf Merge pull request #2689 from ckennelly/aliasing-fixed32-fixed64
Avoid aliasing CodedInputStream::buffer_ when parsing little endian integers
2017-02-14 15:11:47 -08:00
Thomas Van Lenten
38c238e35e Improve support for plugin parameters.
--[name]_opt support depended on the plugin being register, and didn't support
working with just --[name]_out directive (where the plugin is found via the
users PATH. This extends the command line handing to allow --[name]_out to
be all it takes for the _opt directive to also be supported.

Fixes https://github.com/google/protobuf/issues/2712
2017-02-14 14:04:29 -05:00
Feng Xiao
d2dfe46b27 Merge pull request #2609 from yixiang/patch-1
Undef TYPE_BOOL to avoid conflict with iOS.
2017-02-13 17:03:55 -08:00
Jie Luo
3f6f73b796 Merge pull request #2701 from anandolee/master
Add csharp compatibility tests against v3.0.0
2017-02-13 10:54:34 -08:00
Feng Xiao
ed423c2c52 Merge pull request #2451 from podsvirov/json-primitive-map
JsonUtilTest: Add ParsePrimitiveMapIn subtest
2017-02-13 10:46:40 -08:00
Feng Xiao
aa78aeba98 Merge pull request #2704 from liutikas/master
Fix compiler warnings about unused variables in wire_format.h
2017-02-13 10:26:09 -08:00
Paul Yang
74eb9a0a30 Add clear method to PHP message (#2700) 2017-02-11 16:36:17 -08:00
Konstantin Podsvirov
46c022a0a9 JsonUtilTest: Add ParsePrimitiveMapIn subtest 2017-02-11 03:39:53 +03:00
Aurimas Liutikas
9079079ec0 Fix compiler warnings about unused variables in wire_format.h 2017-02-10 16:23:49 -08:00
Jonathan Hseu
ef927cc428 Switch to gcc atomic intrinsics for macOS and delete the file that uses (#2699)
the deprecated atomics.
2017-02-10 14:55:34 -08:00
Jie Luo
7288689d8c Add csharp compatibility tests against v3.0.0 and run on Travis. 2017-02-10 13:40:16 -08:00
Feng Xiao
1d2736f24d Merge pull request #2656 from pcj/patch-1
Add bazel protobuf resources
2017-02-10 10:47:48 -08:00
Jie Luo
9f09d1804a Add proto and test files for csharp compatibility tests against v3.0.0.
All the files are copied from 3.0.0 (JosnFormaterTest was deleted)
2017-02-09 16:43:18 -08:00
Jie Luo
c6e0d0e7f3 Merge pull request #2647 from anandolee/master
Fix python compatibility test
2017-02-09 16:32:08 -08:00
Jie Luo
42e1e2abef Fix python compatibility test when a new generated code imports an old version(2.6.1 or older) generated code. 2017-02-09 11:08:10 -08:00
Feng Xiao
e844510f44 Merge pull request #2692 from cgrushko/patch-3
Update load() statement to latest style
2017-02-08 13:02:18 -08:00
cgrushko
65a4d20deb Update load() statement to latest style
The first argument is currently implicitly a .bzl file.
Change this to be explicit.
2017-02-08 15:23:57 -05:00
Feng Xiao
a60cc08d83 Merge pull request #2691 from cgrushko/patch-3
Bazel can build protobuf when it's not in the root
2017-02-08 10:45:47 -08:00
Paul Yang
cba04b19e8 Implement json encoding decoding for php. (#2682) 2017-02-08 10:27:54 -08:00
cgrushko
6fffd4adb4 Bazel can build protobuf when it's not in the root
That is, Bazel can now build protobuf when the latter resides in a subdirectory of a project.
2017-02-08 12:19:40 -05:00
Chris Kennelly
56da82820e Avoid aliasing CodedInputStream::buffer_ when parsing little endian integers.
This eliminates an unnecessary reload of buffer_ that occurs (before
this change) after the store to *value.
2017-02-07 17:41:16 -08:00
Paul Yang
c00274313d Add fixed version to phpunit used in travis (#2673) 2017-02-07 10:55:48 -08:00
Thomas Van Lenten
36f51f963c Merge pull request #2681 from sergiocampama/spaces
Removes trailing whitespaces
2017-02-07 11:59:59 -05:00
Sergio Campama
e7f5c9d071 Removes trailing whitespaces 2017-02-07 11:57:53 -05:00
Paul Yang
5a3405c51a Update upb for php. (#2662) 2017-02-06 12:40:51 -08:00
Jon Skeet
bd29f86804 Fix CopyTo argument validation
Fixes #2669.
2017-02-06 18:24:19 +00:00
Chris Kennelly
36f68e02d5 Inline branch-less VarintSize32/VarintSize64 implementations. 2017-02-02 16:33:02 -08:00
Paul Yang
39756643df Add conformance test for php (#2655) 2017-02-01 12:47:58 -08:00
Paul Cody Johnston
7b54b34c1e Add bazel protobuf resources 2017-02-01 07:16:22 -07:00
Paul Yang
7f3e237071 Merge 3.2.x branch into master (#2648)
* Down-integrate internal changes to github.

* Update conformance test failure list.

* Explicitly import used class in nano test to avoid random test fail.

* Update _GNUC_VER to use the correct implementation of atomic operation
on Mac.

* maps_test.js: check whether Symbol is defined before using it (#2524)

Symbol is not yet available on older versions of Node.js and so this
test fails with them. This change just directly checks whether Symbol is
available before we try to use it.

* Added well_known_types_embed.cc to CLEANFILES so that it gets cleaned up

* Updated Makefile.am to fix out-of-tree builds

* Added Bazel genrule for generating well_known_types_embed.cc

In pull request #2517 I made this change for the CMake and autotools
builds but forgot to do it for the Bazel build.

* Update _GNUC_VER to use the correct implementation of atomic operation on Mac.

* Add new js file in extra dist.

* Bump version number to 3.2.0

* Fixed issue with autoloading - Invalid paths (#2538)

* PHP fix int64 decoding (#2516)

* fix int64 decoding

* fix int64 decoding + tests

* Fix int64 decoding on 32-bit machines.

* Fix warning in compiler/js/embed.cc

embed.cc: In function ‘std::string CEscape(const string&)’:
embed.cc:51:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 0; i < str.size(); ++i) {
                                ^

* Fix include in auto-generated well_known_types_embed.cc

Restore include style fix (e3da722) that has been trampled by
auto-generation of well_known_types_embed.cc

* Fixed cross compilations with the Autotools build

Pull request #2517 caused cross compilations to start failing, because
the js_embed binary was being built to run on the target platform
instead of on the build machine. This change updates the Autotools build
to use the AX_PROG_CXX_FOR_BUILD macro to find a suitable compiler for
the build machine and always use that when building js_embed.

* Minor fix for autocreated object repeated fields and maps.

- If setting/clearing a repeated field/map that was objects, check the class
  before checking the autocreator.
- Just to be paranoid, don’t mutate within copy/mutableCopy for the autocreated
  classes to ensure there is less chance of issues if someone does something
  really crazy threading wise.
- Some more tests for the internal AutocreatedArray/AutocreatedDictionary
  classes to ensure things are working as expected.
- Add Xcode 8.2 to the full_mac_build.sh supported list.

* Fix generation of extending nested messages in JavaScript (#2439)

* Fix generation of extending nested messages in JavaScript

* Added missing test8.proto to build

* Fix generated code when there is no namespace but there is enum definition.

* Decoding unknown field should succeed.

* Add embed.cc in src/Makefile.am to fix dist check.

* Fixed "make distcheck" for the Autotools build

To make the test pass I needed to fix out-of-tree builds and update
EXTRA_DIST and CLEANFILES.

* Remove redundent embed.cc from src/Makefile.am

* Update version number to 3.2.0-rc.1 (#2578)

* Change protoc-artifacts version to 3.2.0-rc.1

* Update version number to 3.2.0rc2

* Update change logs for 3.2.0 release.

* Update php README

* Update upb, fixes some bugs (including a hash table problem). (#2611)

* Update upb, fixes some bugs (including a hash table problem).

* Ruby: added a test for the previous hash table corruption.

Verified that this triggers the bug in the currently released
version.

* Ruby: bugfix for SEGV.

* Ruby: removed old code for dup'ing defs.

* Reverting deployment target to 7.0 (#2618)

The Protobuf library doesn’t require the 7.1 deployment target so
reverting it back to 7.0

* Fix typo that breaks builds on big-endian (#2632)

* Bump version number to 3.2.0
2017-01-31 09:17:32 -08:00
Joshua Haberman
9d3288e651 Merge pull request #2226 from kchodorow/master
Create paths for external repositories in a way that is forward and backward compatible
2017-01-30 13:45:34 -08:00
Alex Ausch
2c36cc30dd cache generated classes, optimization and quick workaround to memory leak 2017-01-30 15:42:01 -05:00
Jon Skeet
afc59ab55a C#: Implement IReadOnlyList<T> in RepeatedField<T>
We explicitly don't do this when targeting .NET 3.5, where the
interface doesn't exist.

No implementation is required, as we're already implementing
everything we need for IList<T>.
2017-01-30 18:58:56 +00:00
Jie Luo
87e4976ba4 Merge pull request #2639 from anandolee/master
Add Oneof custom options test
2017-01-28 15:31:43 -08:00
michaelpengcn
a83ac8663f fix compile error on centos in metadata.h for constructors. (#2599) 2017-01-27 16:40:53 -08:00
Paul Yang
a323f1e65d Oneof accessor should return the field name that is actually set. (#2631) 2017-01-27 13:17:54 -08:00
Jie Luo
ccb76fff44 Add Oneof custom options test 2017-01-27 11:52:32 -08:00
Jie Luo
5af0b547de Merge pull request #2619 from anandolee/master
Add python compatibility tests against v2.5.0
2017-01-27 10:18:35 -08:00
Jie Luo
1f09786229 Merge pull request #2633 from anandolee/jieluo_branch1
Allow OneofOptions to be extended in proto3.
2017-01-26 14:00:08 -08:00
Jie Luo
ea51149100 Add python compatibility tests against v2.5.0 amd run on Travis. 2017-01-26 11:05:16 -08:00
Jie Luo
c15217f922 Allow OneofOptions to be extended in proto3. 2017-01-25 16:22:15 -08:00
Thomas Van Lenten
c2a5669773 Merge pull request #2626 from sergiocampama/8_3
Adds nullability modifiers to resolve Xcode 8.3 warnings

Fixes #2625
2017-01-25 17:45:17 -05:00
Daniel Ylitalo
32fa55e666 FreeBSD compatibility 2017-01-25 22:04:11 +01:00
Kristina Chodorow
4e7ecde15c Update genfiles paths to work with a different execroot arrangement
Bazel is changing the way the execution root is organized (see https://github.com/bazelbuild/bazel/issues/1681
for details) and this updates the protobuf path logic to work with both old
and new versions of Bazel.
2017-01-25 14:10:56 -05:00
Sergio Campama
3d7b42d1a6 Adds nullability modifiers to resolve Xcode 8.3 warnings 2017-01-25 11:58:17 -05:00
Jie Luo
140e28d12e Add python compatibility tests against v2.5.0: copy tests and proto files from v2.5.0 2017-01-23 15:05:19 -08:00
Adam Cozzette
0aa5af3e68 Merge pull request #2614 from acozzette/gzip-output-stream-options
Set LIBPROTOBUF_EXPORT on GzipOutputStream::Options
2017-01-23 09:51:29 -08:00
Adam Cozzette
a101fa5289 Set LIBPROTOBUF_EXPORT on GzipOutputStream::Options
This fixes issue #2610.
2017-01-20 15:39:34 -08:00
Sean Lu
e41b667da5 Undef TYPE_BOOL to avoid conflict with iOS.
TYPE_BOOL is defined as a macro in <ConditionalMacros.h>, which gets implicitly included in almost all iOS source files.

This fixes complaints like http://go/soverflow/15759559

For some context, here is how TYPE_BOOL is defined in ConditionalMacros.h

  #ifdef __cplusplus
     #define TYPE_BOOL                1
  #else
     #define TYPE_BOOL                0
  #endif
2017-01-19 11:56:08 -08:00
Jon Skeet
047575f20c Support custom options in C#
This consists of:
- Changing the codegen for the fixed set of options protos, to parse unknown fields instead of skipping them
- Add a new CustomOptions type in the C# support library
- Expose CustomOptions properties from the immutable proto wrappers in the support library

Only single-value options are currently supported, and fetching options values requires getting the type right
and knowing the field number. Both of these can be addressed at a later time.

Fixes #2143, at least as a first pass.
2017-01-19 06:46:04 +00:00
Thomas Van Lenten
eed9951991 Merge pull request #2591 from thomasvl/objc_timestamps_take2
Timestamp helper fix, Duration helper cleanup.
2017-01-17 10:10:17 -05:00
goorov
24908e1b32 Update AbstractMessage.java
Apply review's comments.
2017-01-13 10:33:42 +03:00
Thomas Van Lenten
d0bc096b4a Timestamp helper fix, Duration helper cleanup.
- The Timestamp proto does not allow for negative nanos fields, so the seconds
  must be shifted and a positive nanos then applied.
- Tweak the helpers on Duration to make it clear there is no "base" time
  involved.
- Update the unittests for duration and timestamp to cover positive and
  negative NSTimeIntervals and what their impact is on the protos.
2017-01-12 19:33:25 -05:00
Thomas Van Lenten
c9cd6acd71 Merge pull request #2587 from google/revert-2586-objc_timestamp
Revert "Fix Timestamps with dates before the Unix epoch that contain fractional seconds."
2017-01-12 16:01:12 -05:00
Thomas Van Lenten
1651342501 Revert "Fix Timestamps with dates before the Unix epoch that contain fractional seconds." 2017-01-12 16:00:13 -05:00
Thomas Van Lenten
cf477d46ca Merge pull request #2586 from thomasvl/objc_timestamp
Fix Timestamps with dates before the Unix epoch that contain fractional seconds.
2017-01-12 15:50:59 -05:00
Thomas Van Lenten
adcccd0f81 Fix Timestamps with dates before the Unix epoch that contain fractional seconds.
The Timestamp proto does not allow for negative nanos fields, so the seconds must be shifted and
a positive nanos then applied.
2017-01-12 15:46:50 -05:00
Feng Xiao
feb78fb293 Merge pull request #2584 from cgrushko/patch-2
Add a proto_lang_toolchain for Java
2017-01-12 10:55:27 -08:00
cgrushko
e4baf3f58a Add a proto_lang_toolchain for Java
This allows easy use of Bazel's java_proto_library native rule.
2017-01-12 12:51:04 -05:00
Adam Cozzette
e53dd99350 Merge pull request #2529 from wackoisgod/master
Class deprecation support
2017-01-12 08:32:36 -08:00
goorov
fac90c66c3 Update AbstractMessage.java
Method Builder#clone() has been changed to bypass Java 1.6 compiler issue.
2017-01-12 09:35:19 +03:00
Andrew Spiering
75ac3973ef Fixing code formatting issues 2017-01-11 11:18:53 -08:00
Andrew Spiering
effcb132e1 Merge branch 'master' of https://github.com/wackoisgod/protobuf 2017-01-11 10:52:21 -08:00
Adam Cozzette
228d242c58 Merge pull request #2567 from acozzette/distcheck-fix
Fixed "make distcheck" for the Autotools build
2017-01-10 12:54:06 -08:00
Jon Skeet
fb71df9f0b Add ByteString.FromStream and ByteString.FromStreamAsync in C#
Fixes #2088.

We now have separate tests for netcoreapp and net45 to test the two branches here.
(netstandard10 doesn't have MemoryStream.GetBuffer)

Although most of this library doesn't have any async functionality,
this feels like a natural place to locally add it.
2017-01-10 13:05:27 +00:00
Jon Skeet
e76d91a9d1 Add global.json file to pick dotnet core SDK version. 2017-01-10 13:05:27 +00:00
Adam Cozzette
0bdf4a617f Fixed "make distcheck" for the Autotools build
To make the test pass I needed to fix out-of-tree builds and update
EXTRA_DIST and CLEANFILES.
2017-01-09 09:38:14 -08:00
Sufir
2bddffc993 PHP fix int64 decoding (#2516)
* fix int64 decoding

* fix int64 decoding + tests
2017-01-08 11:50:50 -08:00
Marcus Longmuir
2c16f6979a Fix generation of extending nested messages in JavaScript (#2439)
* Fix generation of extending nested messages in JavaScript

* Added missing test8.proto to build
2017-01-06 16:59:47 -08:00
Joshua Haberman
ffa71f8007 A few more cases for binary conformance tests. (#2500)
* A few more cases for binary conformance tests.

* over-encoded varints (encoded in more bytes than are necessary).
* truncated varints (>32 bits for 32-bit types).

* Fixed Python decoding bug with 32-bit varints.

* Fixed 1L -> 1LL for 32-bit platforms.
2017-01-06 16:58:21 -08:00
Adam Cozzette
1041710fce Merge pull request #2565 from acozzette/cross-compilation
Fixed cross compilations with the Autotools build
2017-01-05 15:28:37 -08:00
Thomas Van Lenten
24f0d5691e Merge pull request #2563 from thomasvl/autocreator_tweaks
Minor fix for autocreated object repeated fields and maps.
2017-01-05 10:26:22 -05:00
Thomas Van Lenten
988ffe0a78 Minor fix for autocreated object repeated fields and maps.
- If setting/clearing a repeated field/map that was objects, check the class
  before checking the autocreator.
- Just to be paranoid, don’t mutate within copy/mutableCopy for the autocreated
  classes to ensure there is less chance of issues if someone does something
  really crazy threading wise.
- Some more tests for the internal AutocreatedArray/AutocreatedDictionary
  classes to ensure things are working as expected.
- Add Xcode 8.2 to the full_mac_build.sh supported list.
2017-01-05 09:15:40 -05:00
Adam Cozzette
2deb139bc9 Merge pull request #2544 from tiziano88/master
Add link to Elm proto plugin
2017-01-04 16:09:41 -08:00
Adam Cozzette
17a8a7619a Merge pull request #2536 from jbrianceau/fix-js-embed-include-style
Fix include in auto-generated well_known_types_embed.cc
2017-01-04 15:08:41 -08:00
Adam Cozzette
c55175cb9f Merge pull request #2564 from acozzette/arena-nc
Removed arena_nc.cc and arena_nc_test.py
2017-01-04 14:17:28 -08:00
Adam Cozzette
a59205215a Removed arena_nc.cc and arena_nc_test.py
This test is undocumented and it looks like it has probably never
worked. Let's just remove it to tidy things up. This fixes issue #2515.
2017-01-04 13:57:11 -08:00
Adam Cozzette
b40d318650 Fixed cross compilations with the Autotools build
Pull request #2517 caused cross compilations to start failing, because
the js_embed binary was being built to run on the target platform
instead of on the build machine. This change updates the Autotools build
to use the AX_PROG_CXX_FOR_BUILD macro to find a suitable compiler for
the build machine and always use that when building js_embed.
2017-01-03 13:14:39 -08:00
NicklasWallgren
4cb113a91b Fixed issue with autoloading - Invalid paths (#2538) 2016-12-28 13:33:36 -08:00
Tiziano Santoro
30250cde5e Add link to Elm proto plugin 2016-12-28 01:02:12 +00:00
Feng Xiao
5f65ee6ac7 Merge pull request #2542 from jbrianceau/fix-embed-cc-warning
Fix warning in compiler/js/embed.cc
2016-12-27 11:00:46 -08:00
Julien Brianceau
4455cdf7ee Fix include in auto-generated well_known_types_embed.cc
Restore include style fix (e3da722) that has been trampled by
auto-generation of well_known_types_embed.cc
2016-12-27 11:50:46 +01:00
Julien Brianceau
05b019aedc Fix warning in compiler/js/embed.cc
embed.cc: In function ‘std::string CEscape(const string&)’:
embed.cc:51:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 0; i < str.size(); ++i) {
                                ^
2016-12-27 09:59:52 +01:00
Adam Cozzette
f52e188fe4 Merge pull request #2523 from jbrianceau/init-index-in-metadata
Init index_in_metadata_ without condition
2016-12-22 12:56:08 -08:00
Feng Xiao
137dc026cf Merge pull request #2525 from camillol/lite
Eliminate redundant methods in C++ generated code for lite protos
2016-12-22 00:27:02 -08:00
Camillo Lugaresi
abe172564e simpler, cheaper callback to LazyStringOutputStream 2016-12-21 20:46:42 -08:00
Camillo Lugaresi
4e229c8b5c add MethodResultCallback_0_0 2016-12-21 20:46:42 -08:00
Julien Brianceau
15a15e336b Init index_in_metadata_ without condition
Chromium MemorySanitizer (MSan) reports use-of-uninitialized-value
of index_in_metadata_ attribute from EnumGenerator class. Fix these
warnings by initializing these attributes without condition.
2016-12-21 22:48:58 +01:00
Andrew Spiering
6c021b3d5f Added the support for class level deprecation which will in turn also deprecate any fields that are currently using that type 2016-12-21 13:29:06 -08:00
Adam Cozzette
d948b66d4f Merge pull request #2521 from acozzette/fix-bazel
Added Bazel genrule for generating well_known_types_embed.cc
2016-12-21 07:21:14 -08:00
Adam Cozzette
5731ca5af0 Added well_known_types_embed.cc to CLEANFILES so that it gets cleaned up 2016-12-20 15:47:51 -08:00
Adam Cozzette
ee0a24346e Updated Makefile.am to fix out-of-tree builds 2016-12-20 15:47:51 -08:00
Adam Cozzette
d1e7bd9842 Added Bazel genrule for generating well_known_types_embed.cc
In pull request #2517 I made this change for the CMake and autotools
builds but forgot to do it for the Bazel build.
2016-12-20 09:08:19 -08:00
Adam Cozzette
cdc2766a5d Merge pull request #2506 from ckennelly/rvalue-setters
Add rvalue setters for non-arena strings on C++11.
2016-12-19 16:51:43 -08:00
Adam Cozzette
bb2c6b21a0 Merge pull request #2505 from ckennelly/master
Remove spurious NULL checks in ArenaStringPtr::CreateInstance.
2016-12-19 16:18:45 -08:00
Chris Kennelly
183d31cbdb Add rvalue setters for non-arena strings on C++11. 2016-12-16 13:50:14 -08:00
Yunlong Liu
ef61a9d313 add a key to ctx.action dict to prevent protoc losing the default env 2016-12-16 00:46:21 -05:00
Chris Kennelly
ba63fa731e Remove spurious NULL checks in ArenaStringPtr::CreateInstance. 2016-12-15 14:43:33 -08:00
Feng Xiao
bd158fc238 Speed up JSON parsing.
It turns out calling StringOutputStream::Next()/BackUp() repeatedly is
very costly in opensource protobuf because it keeps resize() the string
back and forth. The current JSON conversion API suffers this problem and
leads to ridiculously long parsing time:
https://github.com/google/protobuf/issues/2305#issuecomment-257785492

This change fixes the problem but caching the buffer of Next() and avoid
calling BackUp() as much as possible.
2016-11-10 18:14:05 -08:00
515 changed files with 43698 additions and 8994 deletions

11
.gitignore vendored
View file

@ -65,6 +65,9 @@ src/js_embed
src/protoc
src/unittest_proto_middleman
# vim generated
*.swp
# Generated test scaffolding
src/no_warning_test.cc
src/no-warning-test
@ -113,14 +116,22 @@ conformance/conformance.pb.cc
conformance/conformance.pb.h
conformance/Conformance.pbobjc.h
conformance/Conformance.pbobjc.m
conformance/conformance_pb.js
conformance/conformance_pb.rb
conformance/failing_tests.txt
conformance/google/
conformance/google-protobuf/
conformance/javac_middleman
conformance/lite/
conformance/nonexistent_tests.txt
conformance/protoc_middleman
conformance/succeeding_tests.txt
conformance/Conformance/
conformance/GPBMetadata/
conformance/Google/
conformance/Protobuf_test_messages/
conformance/conformance-php
conformance/conformance-php-c
# php test output
composer.lock

View file

@ -32,6 +32,7 @@ env:
- CONFIG=ruby22
- CONFIG=jruby
- CONFIG=php5.6_mac
- CONFIG=php7.0_mac
matrix:
exclude:
# It's nontrivial to programmatically install a new JDK from the command
@ -63,6 +64,10 @@ matrix:
# fetch pre-built Linux protoc binaries in the test.
- os: linux
env: CONFIG=java_compatibility
# The Python compatibility test currently only runs on Linux because it will
# fetch pre-built Linux protoc binaries in the test.
- os: linux
env: CONFIG=python_compatibility
allow_failures:
# These currently do not work on OS X but are being worked on by @haberman.
- os: osx

54
BUILD
View file

@ -27,11 +27,11 @@ config_setting(
# Android builds do not need to link in a separate pthread library.
LINK_OPTS = select({
":android": [],
"//conditions:default": ["-lpthread"],
"//conditions:default": ["-lpthread", "-lm"],
})
load(
"protobuf",
":protobuf.bzl",
"cc_proto_library",
"py_proto_library",
"internal_copied_filegroup",
@ -145,6 +145,7 @@ cc_library(
"src/google/protobuf/timestamp.pb.cc",
"src/google/protobuf/type.pb.cc",
"src/google/protobuf/unknown_field_set.cc",
"src/google/protobuf/util/delimited_message_util.cc",
"src/google/protobuf/util/field_comparator.cc",
"src/google/protobuf/util/field_mask_util.cc",
"src/google/protobuf/util/internal/datapiece.cc",
@ -181,6 +182,17 @@ cc_library(
deps = [":protobuf_lite"],
)
# This provides just the header files for use in projects that need to build
# shared libraries for dynamic loading. This target is available until Bazel
# adds native support for such use cases.
# TODO(keveman): Remove this target once the support gets added to Bazel.
cc_library(
name = "protobuf_headers",
hdrs = glob(["src/**/*.h"]),
includes = ["src/"],
visibility = ["//visibility:public"],
)
objc_library(
name = "protobuf_objc",
hdrs = ["objectivec/GPBProtocolBuffers.h"],
@ -194,6 +206,7 @@ RELATIVE_WELL_KNOWN_PROTOS = [
"google/protobuf/any.proto",
"google/protobuf/api.proto",
"google/protobuf/compiler/plugin.proto",
"google/protobuf/compiler/profile.proto",
"google/protobuf/descriptor.proto",
"google/protobuf/duration.proto",
"google/protobuf/empty.proto",
@ -338,6 +351,7 @@ cc_library(
"src/google/protobuf/compiler/php/php_generator.cc",
"src/google/protobuf/compiler/plugin.cc",
"src/google/protobuf/compiler/plugin.pb.cc",
"src/google/protobuf/compiler/profile.pb.cc",
"src/google/protobuf/compiler/python/python_generator.cc",
"src/google/protobuf/compiler/ruby/ruby_generator.cc",
"src/google/protobuf/compiler/subprocess.cc",
@ -389,6 +403,9 @@ RELATIVE_TEST_PROTOS = [
"google/protobuf/unittest_enormous_descriptor.proto",
"google/protobuf/unittest_import.proto",
"google/protobuf/unittest_import_public.proto",
"google/protobuf/unittest_lazy_dependencies.proto",
"google/protobuf/unittest_lazy_dependencies_custom_option.proto",
"google/protobuf/unittest_lazy_dependencies_enum.proto",
"google/protobuf/unittest_lite_imports_nonlite.proto",
"google/protobuf/unittest_mset.proto",
"google/protobuf/unittest_mset_wire_format.proto",
@ -465,6 +482,7 @@ cc_test(
"src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_unittest.cc",
"src/google/protobuf/compiler/cpp/metadata_test.cc",
"src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc",
"src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc",
"src/google/protobuf/compiler/importer_unittest.cc",
"src/google/protobuf/compiler/java/java_doc_comment_unittest.cc",
@ -510,6 +528,7 @@ cc_test(
"src/google/protobuf/stubs/type_traits_unittest.cc",
"src/google/protobuf/text_format_unittest.cc",
"src/google/protobuf/unknown_field_set_unittest.cc",
"src/google/protobuf/util/delimited_message_util_test.cc",
"src/google/protobuf/util/field_comparator_test.cc",
"src/google/protobuf/util/field_mask_util_test.cc",
"src/google/protobuf/util/internal/default_value_objectwriter_test.cc",
@ -530,6 +549,10 @@ cc_test(
":test_plugin",
] + glob([
"src/google/protobuf/**/*",
# Files for csharp_bootstrap_unittest.cc.
"conformance/**/*",
"csharp/src/**/*",
"examples/**/*",
]),
includes = [
"src/",
@ -557,6 +580,7 @@ java_library(
]) + [
":gen_well_known_protos_java",
],
javacopts = ["-source 6"],
visibility = ["//visibility:public"],
)
@ -565,12 +589,12 @@ java_library(
srcs = glob([
"java/util/src/main/java/com/google/protobuf/util/*.java",
]),
visibility = ["//visibility:public"],
deps = [
"protobuf_java",
"//external:gson",
"//external:guava",
],
visibility = ["//visibility:public"],
)
################################################################################
@ -591,8 +615,8 @@ py_library(
"python/google/protobuf/internal/test_util.py",
],
),
srcs_version = "PY2AND3",
imports = ["python"],
srcs_version = "PY2AND3",
)
cc_binary(
@ -657,8 +681,8 @@ config_setting(
internal_copied_filegroup(
name = "protos_python",
srcs = WELL_KNOWN_PROTOS,
strip_prefix = "src",
dest = "python",
strip_prefix = "src",
)
# TODO(dzc): Remove this once py_proto_library can have labels in srcs, in
@ -680,7 +704,7 @@ py_proto_library(
protoc = ":protoc",
py_libs = [
":python_srcs",
"//external:six"
"//external:six",
],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
@ -694,13 +718,14 @@ py_proto_library(
internal_copied_filegroup(
name = "protos_python_test",
srcs = LITE_TEST_PROTOS + TEST_PROTOS,
strip_prefix = "src",
dest = "python",
strip_prefix = "src",
)
# TODO(dzc): Remove this once py_proto_library can have labels in srcs, in
# which case we can simply add :protos_python_test in srcs.
COPIED_LITE_TEST_PROTOS = ["python/" + s for s in RELATIVE_LITE_TEST_PROTOS]
COPIED_TEST_PROTOS = ["python/" + s for s in RELATIVE_TEST_PROTOS]
py_proto_library(
@ -770,8 +795,15 @@ internal_protobuf_py_tests(
)
proto_lang_toolchain(
name = "cc_toolchain",
runtime = ":protobuf",
command_line = "--cpp_out=$(OUT)",
visibility = ["//visibility:public"],
name = "cc_toolchain",
command_line = "--cpp_out=$(OUT)",
runtime = ":protobuf",
visibility = ["//visibility:public"],
)
proto_lang_toolchain(
name = "java_toolchain",
command_line = "--java_out=$(OUT)",
runtime = ":protobuf_java",
visibility = ["//visibility:public"],
)

View file

@ -1,3 +1,111 @@
2017-04-05 version 3.3.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
Planned Future Changes
* There are some changes that are not included in this release but are
planned for the near future:
- Preserve unknown fields in proto3: please read this doc:
https://docs.google.com/document/d/1KMRX-G91Aa-Y2FkEaHeeviLRRNblgIahbsk4wA14gRk/view
for the timeline and follow up this github issue:
https://github.com/google/protobuf/issues/272
for discussion.
- Make C++ implementation C++11 only: we plan to require C++11 to build
protobuf code starting from 3.4.0 or 3.5.0 release. Please join this
github issue:
https://github.com/google/protobuf/issues/2780
to provide your feedback.
C++
* Fixed map fields serialization of DynamicMessage to correctly serialize
both key and value regardless of their presence.
* Parser now rejects field number 0 correctly.
* New API Message::SpaceUsedLong() thats equivalent to
Message::SpaceUsed() but returns the value in size_t.
* JSON support
- New flag always_print_enums_as_ints in JsonPrintOptions.
- New flag preserve_proto_field_names in JsonPrintOptions. It will instruct
the JSON printer to use the original field name declared in the .proto
file instead of converting them to lowerCamelCase when printing JSON.
- JsonPrintOptions.always_print_primtive_fields now works for oneof message
fields.
- Fixed a bug that doesnt allow different fields to set the same json_name
value.
- Fixed a performance bug that causes excessive memory copy when printing
large messages.
* Various performance optimizations.
Java
* Map field setters eagerly validate inputs and throw NullPointerExceptions
as appropriate.
* Added ByteBuffer overloads to the generated parsing methods and the Parser
interface.
* proto3 enum's getNumber() method now throws on UNRECOGNIZED values.
* Output of JsonFormat is now locale independent.
Python
* Added FindServiceByName() in the pure-Python DescriptorPool. This works only
for descriptors added with DescriptorPool.Add(). Generated descriptor_pool
does not support this yet.
* Added a descriptor_pool parameter for parsing Any in text_format.Parse().
* descriptor_pool.FindFileContainingSymbol() now is able to find nested
extensions.
* Extending empty [] to repeated field now sets parent message presence.
PHP
* Added file option php_class_prefix. The prefix will be prepended to all
generated classes defined in the file.
* When encoding, negative int32 values are sign-extended to int64.
* Repeated/Map field setter accepts a regular PHP array. Type checking is
done on the array elements.
* encode/decode are renamed to serializeToString/mergeFromString.
* Added mergeFrom, clear method on Message.
* Fixed a bug that oneof accessor didnt return the field name that is
actually set.
* C extension now works with php7.
* This is the first GA release of PHP. We guarantee that old generated code
can always work with new runtime and new generated code.
Objective-C
* Fixed help for GPBTimestamp for dates before the epoch that contain
fractional seconds.
* Added GPBMessageDropUnknownFieldsRecursively() to remove unknowns from a
message and any sub messages.
* Addressed a threading race in extension registration/lookup.
* Increased the max message parsing depth to 100 to match the other languages.
* Removed some use of dispatch_once in favor of atomic compare/set since it
needs to be heap based.
* Fixes for new Xcode 8.3 warnings.
C#
* Fixed MapField.Values.CopyTo, which would throw an exception unnecessarily
if provided exactly the right size of array to copy to.
* Fixed enum JSON formatting when multiple names mapped to the same numeric
value.
* Added JSON formatting option to format enums as integers.
* Modified RepeatedField<T> to implement IReadOnlyList<T>.
* Introduced the start of custom option handling; it's not as pleasant as it
might be, but the information is at least present. We expect to extend code
generation to improve this in the future.
* Introduced ByteString.FromStream and ByteString.FromStreamAsync to
efficiently create a ByteString from a stream.
* Added whole-message deprecation, which decorates the class with [Obsolete].
Ruby
* Fixed Message#to_h for messages with map fields.
* Fixed memcpy() in binary gems to work for old glibc, without breaking the
build for non-glibc libcs like musl.
Javascript
* Added compatibility tests for version 3.0.0.
* Added conformance tests.
* Fixed serialization of extensions: we need to emit a value even if it is
falsy (like the number 0).
* Use closurebuilder.py in favor of calcdeps.py for compiling JavaScript.
2017-01-23 version 3.2.0 (C++/Java/Python/PHP/Ruby/Objective-C/C#/JavaScript/Lite)
General
* Added protoc version number to protoc plugin protocol. It can be used by
@ -1381,7 +1489,7 @@
2008-09-29 version 2.0.2:
General
* License changed from Apache 2.0 to New BSD.
* License changed from Apache 2.0 to 3-Clause BSD.
* It is now possible to define custom "options", which are basically
annotations which may be placed on definitions in a .proto file.
For example, you might define a field option called "foo" like so:

View file

@ -60,6 +60,7 @@ csharp_EXTRA_DIST= \
csharp/keys/Google.Protobuf.public.snk \
csharp/keys/Google.Protobuf.snk \
csharp/keys/README.md \
csharp/protos/unittest_custom_options_proto3.proto \
csharp/protos/unittest_issues.proto \
csharp/src/AddressBook/AddPerson.cs \
csharp/src/AddressBook/Addressbook.cs \
@ -82,6 +83,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs \
csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs \
csharp/src/Google.Protobuf.Test/Compatibility/PropertyInfoExtensionsTest.cs \
csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs \
csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs \
csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs \
csharp/src/Google.Protobuf.Test/EqualityTester.cs \
@ -92,6 +94,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs \
csharp/src/Google.Protobuf.Test/JsonParserTest.cs \
csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs \
csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs \
csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs \
csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs \
csharp/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs \
@ -101,6 +104,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs \
csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs \
@ -122,6 +126,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs \
csharp/src/Google.Protobuf/Collections/RepeatedField.cs \
csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs \
csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs \
csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \
csharp/src/Google.Protobuf/FieldCodec.cs \
csharp/src/Google.Protobuf/FrameworkPortability.cs \
@ -140,6 +145,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/MessageParser.cs \
csharp/src/Google.Protobuf/ProtoPreconditions.cs \
csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs \
csharp/src/Google.Protobuf/Reflection/CustomOptions.cs \
csharp/src/Google.Protobuf/Reflection/Descriptor.cs \
csharp/src/Google.Protobuf/Reflection/DescriptorBase.cs \
csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs \
@ -186,6 +192,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs \
csharp/src/Google.Protobuf/WireFormat.cs \
csharp/src/Google.Protobuf/project.json \
csharp/src/global.json \
csharp/src/packages/repositories.config
java_EXTRA_DIST= \
@ -240,6 +247,7 @@ java_EXTRA_DIST=
java/core/src/main/java/com/google/protobuf/MutabilityOracle.java \
java/core/src/main/java/com/google/protobuf/NioByteString.java \
java/core/src/main/java/com/google/protobuf/Parser.java \
java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java \
java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java \
java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \
java/core/src/main/java/com/google/protobuf/ProtocolStringList.java \
@ -577,6 +585,21 @@ objectivec_EXTRA_DIST= \
Protobuf.podspec
php_EXTRA_DIST= \
php/ext/google/protobuf/utf8.h \
php/ext/google/protobuf/message.c \
php/ext/google/protobuf/utf8.c \
php/ext/google/protobuf/package.xml \
php/ext/google/protobuf/upb.h \
php/ext/google/protobuf/array.c \
php/ext/google/protobuf/encode_decode.c \
php/ext/google/protobuf/protobuf.h \
php/ext/google/protobuf/type_check.c \
php/ext/google/protobuf/def.c \
php/ext/google/protobuf/storage.c \
php/ext/google/protobuf/map.c \
php/ext/google/protobuf/config.m4 \
php/ext/google/protobuf/upb.c \
php/ext/google/protobuf/protobuf.c \
php/src/phpdoc.dist.xml \
php/src/Google/Protobuf/Internal/DescriptorPool.php \
php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php \
@ -623,41 +646,30 @@ php_EXTRA_DIST= \
php/src/Google/Protobuf/Internal/EnumBuilderContext.php \
php/src/Google/Protobuf/Internal/GPBUtil.php \
php/src/Google/Protobuf/Internal/FieldOptions_CType.php \
php/src/Google/Protobuf/Internal/GPBDecodeException.php \
php/src/Google/Protobuf/descriptor.php \
php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php \
php/tests/array_test.php \
php/tests/autoload.php \
php/tests/encode_decode_test.php \
php/tests/test.sh \
php/tests/gdb_test.sh \
php/tests/generated_class_test.php \
php/tests/array_test.php \
php/tests/php_implementation_test.php \
php/tests/proto/test_include.proto \
php/tests/map_field_test.php \
php/tests/test_base.php \
php/tests/proto/test_no_namespace.proto \
php/tests/test_util.php \
php/tests/proto/test.proto \
php/tests/memory_leak_test.php \
php/tests/php_implementation_test.php \
php/tests/proto/test_import_descriptor_proto.proto \
php/tests/proto/test_include.proto \
php/tests/proto/test.proto \
php/tests/proto/test_prefix.proto \
php/tests/proto/test_no_namespace.proto \
php/tests/test.sh \
php/tests/test_base.php \
php/tests/test_util.php \
php/tests/well_known_test.php \
php/README.md \
php/ext/google/protobuf/utf8.h \
php/ext/google/protobuf/message.c \
php/ext/google/protobuf/utf8.c \
php/ext/google/protobuf/package.xml \
php/ext/google/protobuf/upb.h \
php/ext/google/protobuf/array.c \
php/ext/google/protobuf/encode_decode.c \
php/ext/google/protobuf/protobuf.h \
php/ext/google/protobuf/type_check.c \
php/ext/google/protobuf/def.c \
php/ext/google/protobuf/storage.c \
php/ext/google/protobuf/map.c \
php/ext/google/protobuf/config.m4 \
php/ext/google/protobuf/upb.c \
php/ext/google/protobuf/protobuf.c \
php/phpunit.xml \
php/composer.json \
php/generate_descriptor_protos.sh \
composer.json
python_EXTRA_DIST= \
@ -701,6 +713,7 @@ python_EXTRA_DIST= \
python/google/protobuf/internal/packed_field_test.proto \
python/google/protobuf/internal/proto_builder_test.py \
python/google/protobuf/internal/python_message.py \
python/google/protobuf/internal/python_protobuf.cc \
python/google/protobuf/internal/reflection_test.py \
python/google/protobuf/internal/service_reflection_test.py \
python/google/protobuf/internal/symbol_database_test.py \
@ -743,13 +756,13 @@ python_EXTRA_DIST= \
python/google/protobuf/pyext/message_module.cc \
python/google/protobuf/pyext/proto2_api_test.proto \
python/google/protobuf/pyext/python.proto \
python/google/protobuf/pyext/python_protobuf.h \
python/google/protobuf/pyext/repeated_composite_container.cc \
python/google/protobuf/pyext/repeated_composite_container.h \
python/google/protobuf/pyext/repeated_scalar_container.cc \
python/google/protobuf/pyext/repeated_scalar_container.h \
python/google/protobuf/pyext/safe_numerics.h \
python/google/protobuf/pyext/scoped_pyobject_ptr.h \
python/google/protobuf/python_protobuf.h \
python/google/protobuf/reflection.py \
python/google/protobuf/service.py \
python/google/protobuf/service_reflection.py \
@ -768,6 +781,15 @@ ruby_EXTRA_DIST= \
ruby/.gitignore \
ruby/README.md \
ruby/Rakefile \
ruby/compatibility_tests/v3.0.0/tests/test_import.proto \
ruby/compatibility_tests/v3.0.0/tests/stress.rb \
ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb \
ruby/compatibility_tests/v3.0.0/tests/generated_code_test.rb \
ruby/compatibility_tests/v3.0.0/tests/generated_code.proto \
ruby/compatibility_tests/v3.0.0/tests/basic.rb \
ruby/compatibility_tests/v3.0.0/test.sh \
ruby/compatibility_tests/v3.0.0/Rakefile \
ruby/compatibility_tests/v3.0.0/README.md \
ruby/ext/google/protobuf_c/defs.c \
ruby/ext/google/protobuf_c/encode_decode.c \
ruby/ext/google/protobuf_c/extconf.rb \

View file

@ -5,10 +5,10 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
s.version = '3.2.1'
s.version = '3.3.0'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/google/protobuf'
s.license = 'New BSD'
s.license = '3-Clause BSD License'
s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' }
s.cocoapods_version = '>= 1.0'

View file

@ -74,4 +74,4 @@ Usage
The complete documentation for Protocol Buffers is available via the
web at:
https://developers.google.com/protocol-buffers/
https://developers.google.com/protocol-buffers/

View file

@ -135,7 +135,7 @@ endif (protobuf_BUILD_SHARED_LIBS)
if (MSVC)
# Build with multiple processes
add_definitions(/MP)
add_definitions(/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305)
add_definitions(/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305 /wd4309)
# Allow big object
add_definitions(/bigobj)
string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR})

View file

@ -14,115 +14,116 @@ mkdir include\google\protobuf\compiler\ruby
mkdir include\google\protobuf\io
mkdir include\google\protobuf\stubs
mkdir include\google\protobuf\util
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.h include\google\protobuf\any.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.pb.h include\google\protobuf\any.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h include\google\protobuf\api.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h include\google\protobuf\arena.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h include\google\protobuf\arenastring.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h include\google\protobuf\compiler\code_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h include\google\protobuf\compiler\command_line_interface.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h include\google\protobuf\compiler\csharp\csharp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h include\google\protobuf\compiler\csharp\csharp_names.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h include\google\protobuf\compiler\java\java_names.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\javanano\javanano_generator.h include\google\protobuf\compiler\javanano\javanano_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\js_generator.h include\google\protobuf\compiler\js\js_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\well_known_types_embed.h include\google\protobuf\compiler\js\well_known_types_embed.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h include\google\protobuf\compiler\objectivec\objectivec_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_helpers.h include\google\protobuf\compiler\objectivec\objectivec_helpers.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h include\google\protobuf\compiler\parser.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h include\google\protobuf\compiler\php\php_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h include\google\protobuf\compiler\plugin.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h include\google\protobuf\compiler\plugin.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h include\google\protobuf\compiler\python\python_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h include\google\protobuf\compiler\ruby\ruby_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h include\google\protobuf\descriptor.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h include\google\protobuf\descriptor.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor_database.h include\google\protobuf\descriptor_database.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.pb.h include\google\protobuf\duration.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h include\google\protobuf\dynamic_message.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h include\google\protobuf\empty.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h include\google\protobuf\extension_set.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h include\google\protobuf\field_mask.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h include\google\protobuf\generated_enum_reflection.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h include\google\protobuf\generated_enum_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h include\google\protobuf\has_bits.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h include\google\protobuf\io\gzip_stream.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\printer.h include\google\protobuf\io\printer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\strtod.h include\google\protobuf\io\strtod.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\tokenizer.h include\google\protobuf\io\tokenizer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream.h include\google\protobuf\io\zero_copy_stream.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl.h include\google\protobuf\io\zero_copy_stream_impl.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl_lite.h include\google\protobuf\io\zero_copy_stream_impl_lite.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map.h include\google\protobuf\map.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry.h include\google\protobuf\map_entry.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry_lite.h include\google\protobuf\map_entry_lite.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field.h include\google\protobuf\map_field.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_inl.h include\google\protobuf\map_field_inl.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_lite.h include\google\protobuf\map_field_lite.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_type_handler.h include\google\protobuf\map_type_handler.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message.h include\google\protobuf\message.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message_lite.h include\google\protobuf\message_lite.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h include\google\protobuf\metadata.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h include\google\protobuf\reflection.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h include\google\protobuf\reflection_ops.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h include\google\protobuf\repeated_field.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h include\google\protobuf\service.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h include\google\protobuf\source_context.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h include\google\protobuf\struct.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomic_sequence_num.h include\google\protobuf\stubs\atomic_sequence_num.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops.h include\google\protobuf\stubs\atomicops.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm64_gcc.h include\google\protobuf\stubs\atomicops_internals_arm64_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_gcc.h include\google\protobuf\stubs\atomicops_internals_arm_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_qnx.h include\google\protobuf\stubs\atomicops_internals_arm_qnx.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_atomicword_compat.h include\google\protobuf\stubs\atomicops_internals_atomicword_compat.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h include\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_gcc.h include\google\protobuf\stubs\atomicops_internals_generic_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_macosx.h include\google\protobuf\stubs\atomicops_internals_macosx.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_mips_gcc.h include\google\protobuf\stubs\atomicops_internals_mips_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h include\google\protobuf\stubs\atomicops_internals_power.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_ppc_gcc.h include\google\protobuf\stubs\atomicops_internals_ppc_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_solaris.h include\google\protobuf\stubs\atomicops_internals_solaris.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h include\google\protobuf\stubs\atomicops_internals_tsan.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h include\google\protobuf\stubs\atomicops_internals_x86_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h include\google\protobuf\stubs\bytestream.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h include\google\protobuf\stubs\callback.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h include\google\protobuf\stubs\casts.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h include\google\protobuf\stubs\fastmem.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h include\google\protobuf\stubs\hash.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h include\google\protobuf\stubs\logging.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h include\google\protobuf\stubs\macros.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h include\google\protobuf\stubs\mutex.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h include\google\protobuf\stubs\port.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\scoped_ptr.h include\google\protobuf\stubs\scoped_ptr.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h include\google\protobuf\stubs\shared_ptr.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h include\google\protobuf\stubs\singleton.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\status.h include\google\protobuf\stubs\status.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h include\google\protobuf\stubs\stl_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stringpiece.h include\google\protobuf\stubs\stringpiece.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\template_util.h include\google\protobuf\stubs\template_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\type_traits.h include\google\protobuf\stubs\type_traits.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h include\google\protobuf\text_format.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h include\google\protobuf\timestamp.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h include\google\protobuf\type.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h include\google\protobuf\util\field_comparator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h include\google\protobuf\util\field_mask_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h include\google\protobuf\util\json_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h include\google\protobuf\util\message_differencer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\time_util.h include\google\protobuf\util\time_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h include\google\protobuf\util\type_resolver.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h include\google\protobuf\util\type_resolver_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite.h include\google\protobuf\wire_format_lite.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite_inl.h include\google\protobuf\wire_format_lite_inl.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wrappers.pb.h include\google\protobuf\wrappers.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.h" include\google\protobuf\any.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.pb.h" include\google\protobuf\any.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h" include\google\protobuf\api.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h" include\google\protobuf\arena.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h" include\google\protobuf\arenastring.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h" include\google\protobuf\compiler\command_line_interface.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h" include\google\protobuf\compiler\cpp\cpp_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h" include\google\protobuf\compiler\csharp\csharp_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h" include\google\protobuf\compiler\csharp\csharp_names.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h" include\google\protobuf\compiler\importer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h" include\google\protobuf\compiler\java\java_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h" include\google\protobuf\compiler\java\java_names.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\javanano\javanano_generator.h" include\google\protobuf\compiler\javanano\javanano_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\js_generator.h" include\google\protobuf\compiler\js\js_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\well_known_types_embed.h" include\google\protobuf\compiler\js\well_known_types_embed.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h" include\google\protobuf\compiler\objectivec\objectivec_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_helpers.h" include\google\protobuf\compiler\objectivec\objectivec_helpers.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h" include\google\protobuf\compiler\parser.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h" include\google\protobuf\compiler\php\php_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\profile.pb.h" include\google\protobuf\compiler\profile.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h" include\google\protobuf\descriptor.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor_database.h" include\google\protobuf\descriptor_database.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.pb.h" include\google\protobuf\duration.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h" include\google\protobuf\dynamic_message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h" include\google\protobuf\field_mask.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h" include\google\protobuf\generated_enum_reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\printer.h" include\google\protobuf\io\printer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\strtod.h" include\google\protobuf\io\strtod.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\tokenizer.h" include\google\protobuf\io\tokenizer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream.h" include\google\protobuf\io\zero_copy_stream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl.h" include\google\protobuf\io\zero_copy_stream_impl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl_lite.h" include\google\protobuf\io\zero_copy_stream_impl_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map.h" include\google\protobuf\map.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry.h" include\google\protobuf\map_entry.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry_lite.h" include\google\protobuf\map_entry_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field.h" include\google\protobuf\map_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_inl.h" include\google\protobuf\map_field_inl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_lite.h" include\google\protobuf\map_field_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_type_handler.h" include\google\protobuf\map_type_handler.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message.h" include\google\protobuf\message.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message_lite.h" include\google\protobuf\message_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h" include\google\protobuf\metadata.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h" include\google\protobuf\reflection.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h" include\google\protobuf\reflection_ops.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h" include\google\protobuf\service.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h" include\google\protobuf\source_context.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h" include\google\protobuf\struct.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomic_sequence_num.h" include\google\protobuf\stubs\atomic_sequence_num.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops.h" include\google\protobuf\stubs\atomicops.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm64_gcc.h" include\google\protobuf\stubs\atomicops_internals_arm64_gcc.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_gcc.h" include\google\protobuf\stubs\atomicops_internals_arm_gcc.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_qnx.h" include\google\protobuf\stubs\atomicops_internals_arm_qnx.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_atomicword_compat.h" include\google\protobuf\stubs\atomicops_internals_atomicword_compat.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h" include\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_gcc.h" include\google\protobuf\stubs\atomicops_internals_generic_gcc.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_mips_gcc.h" include\google\protobuf\stubs\atomicops_internals_mips_gcc.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h" include\google\protobuf\stubs\atomicops_internals_power.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_ppc_gcc.h" include\google\protobuf\stubs\atomicops_internals_ppc_gcc.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_solaris.h" include\google\protobuf\stubs\atomicops_internals_solaris.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h" include\google\protobuf\stubs\atomicops_internals_tsan.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h" include\google\protobuf\stubs\atomicops_internals_x86_gcc.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h" include\google\protobuf\stubs\atomicops_internals_x86_msvc.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" include\google\protobuf\stubs\bytestream.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h" include\google\protobuf\stubs\mutex.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h" include\google\protobuf\stubs\once.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h" include\google\protobuf\stubs\platform_macros.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h" include\google\protobuf\stubs\port.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\scoped_ptr.h" include\google\protobuf\stubs\scoped_ptr.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h" include\google\protobuf\stubs\shared_ptr.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h" include\google\protobuf\stubs\singleton.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\status.h" include\google\protobuf\stubs\status.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h" include\google\protobuf\stubs\stl_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stringpiece.h" include\google\protobuf\stubs\stringpiece.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\template_util.h" include\google\protobuf\stubs\template_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\type_traits.h" include\google\protobuf\stubs\type_traits.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h" include\google\protobuf\text_format.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h" include\google\protobuf\timestamp.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h" include\google\protobuf\type.pb.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h" include\google\protobuf\unknown_field_set.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\delimited_message_util.h" include\google\protobuf\util\delimited_message_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h" include\google\protobuf\util\field_comparator.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h" include\google\protobuf\util\field_mask_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h" include\google\protobuf\util\json_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h" include\google\protobuf\util\message_differencer.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\time_util.h" include\google\protobuf\util\time_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h" include\google\protobuf\util\type_resolver.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h" include\google\protobuf\util\type_resolver_util.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h" include\google\protobuf\wire_format.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite.h" include\google\protobuf\wire_format_lite.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite_inl.h" include\google\protobuf\wire_format_lite_inl.h
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wrappers.pb.h" include\google\protobuf\wrappers.pb.h

View file

@ -20,18 +20,12 @@ install(TARGETS protoc EXPORT protobuf-targets
file(STRINGS extract_includes.bat.in _extract_strings
REGEX "^copy")
foreach(_extract_string ${_extract_strings})
string(REPLACE "copy \${PROTOBUF_SOURCE_WIN32_PATH}\\" ""
_extract_string ${_extract_string})
string(REPLACE "\\" "/" _extract_string ${_extract_string})
string(REGEX MATCH "^[^ ]+"
_extract_from ${_extract_string})
string(REGEX REPLACE "^${_extract_from} ([^$]+)" "\\1"
_extract_to ${_extract_string})
get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/${_extract_from}" ABSOLUTE)
get_filename_component(_extract_name ${_extract_to} NAME)
get_filename_component(_extract_to ${_extract_to} PATH)
string(REPLACE "include/" "${CMAKE_INSTALL_INCLUDEDIR}/"
_extract_to "${_extract_to}")
string(REGEX REPLACE "^.* .+ include\\\\(.+)$" "\\1"
_header ${_extract_string})
string(REPLACE "\\" "/" _header ${_header})
get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/../src/${_header}" ABSOLUTE)
get_filename_component(_extract_name ${_header} NAME)
get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" PATH)
if(EXISTS "${_extract_from}")
install(FILES "${_extract_from}"
DESTINATION "${_extract_to}"

View file

@ -30,6 +30,7 @@ set(libprotobuf_files
${protobuf_source_dir}/src/google/protobuf/timestamp.pb.cc
${protobuf_source_dir}/src/google/protobuf/type.pb.cc
${protobuf_source_dir}/src/google/protobuf/unknown_field_set.cc
${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util.cc
${protobuf_source_dir}/src/google/protobuf/util/field_comparator.cc
${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/datapiece.cc

View file

@ -88,6 +88,7 @@ set(libprotoc_files
${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc
${protobuf_source_dir}/src/google/protobuf/compiler/plugin.cc
${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc
${protobuf_source_dir}/src/google/protobuf/compiler/profile.pb.cc
${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.cc
${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc
${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc

View file

@ -17,6 +17,7 @@ add_library(gmock STATIC
${protobuf_source_dir}/gmock/src/gmock-all.cc
${protobuf_source_dir}/gmock/gtest/src/gtest-all.cc
)
target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT})
add_library(gmock_main STATIC ${protobuf_source_dir}/gmock/src/gmock_main.cc)
target_link_libraries(gmock_main gmock)
@ -42,6 +43,9 @@ set(tests_protos
google/protobuf/unittest_empty.proto
google/protobuf/unittest_import.proto
google/protobuf/unittest_import_public.proto
google/protobuf/unittest_lazy_dependencies.proto
google/protobuf/unittest_lazy_dependencies_custom_option.proto
google/protobuf/unittest_lazy_dependencies_enum.proto
google/protobuf/unittest_lite_imports_nonlite.proto
google/protobuf/unittest_mset.proto
google/protobuf/unittest_mset_wire_format.proto
@ -122,6 +126,7 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/metadata_test.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/importer_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
@ -167,6 +172,7 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/stubs/type_traits_unittest.cc
${protobuf_source_dir}/src/google/protobuf/text_format_unittest.cc
${protobuf_source_dir}/src/google/protobuf/unknown_field_set_unittest.cc
${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util_test.cc
${protobuf_source_dir}/src/google/protobuf/util/field_comparator_test.cc
${protobuf_source_dir}/src/google/protobuf/util/field_mask_util_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
@ -204,7 +210,7 @@ set(lite_test_files
${protobuf_source_dir}/src/google/protobuf/lite_unittest.cc
)
add_executable(lite-test ${lite_test_files} ${common_lite_test_files} ${lite_test_proto_files})
target_link_libraries(lite-test libprotobuf-lite)
target_link_libraries(lite-test libprotobuf-lite gmock_main)
set(lite_arena_test_files
${protobuf_source_dir}/src/google/protobuf/lite_arena_unittest.cc

View file

@ -17,7 +17,7 @@ AC_PREREQ(2.59)
# In the SVN trunk, the version should always be the next anticipated release
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
# the size of one file name in the dist tarfile over the 99-char limit.)
AC_INIT([Protocol Buffers],[3.2.0],[protobuf@googlegroups.com],[protobuf])
AC_INIT([Protocol Buffers],[3.3.0],[protobuf@googlegroups.com],[protobuf])
AM_MAINTAINER_MODE([enable])
@ -93,6 +93,25 @@ ACX_CHECK_SUNCC
# to the link
AC_PROG_LIBTOOL
# Check whether the linker supports version scripts
AC_MSG_CHECKING([whether the linker supports version scripts])
save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
cat > conftest.map <<EOF
{
global:
main;
local:
*;
};
EOF
AC_LINK_IFELSE(
[AC_LANG_SOURCE([int main() { return 0; }])],
[have_ld_version_script=yes; AC_MSG_RESULT(yes)],
[have_ld_version_script=no; AC_MSG_RESULT(no)])
LDFLAGS=$save_LDFLAGS
AM_CONDITIONAL([HAVE_LD_VERSION_SCRIPT], [test "$have_ld_version_script" == "yes"])
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdlib.h unistd.h])

View file

@ -21,6 +21,7 @@ other_language_protoc_outputs = \
conformance_pb2.py \
Conformance.pbobjc.h \
Conformance.pbobjc.m \
conformance_pb.js \
conformance_pb.rb \
com/google/protobuf/Any.java \
com/google/protobuf/AnyOrBuilder.java \
@ -92,7 +93,40 @@ other_language_protoc_outputs = \
google/protobuf/wrappers.pb.cc \
google/protobuf/wrappers.pb.h \
google/protobuf/wrappers.rb \
google/protobuf/wrappers_pb2.py
google/protobuf/wrappers_pb2.py \
Conformance/ConformanceRequest.php \
Conformance/ConformanceResponse.php \
Conformance/WireFormat.php \
GPBMetadata/Conformance.php \
GPBMetadata/Google/Protobuf/Any.php \
GPBMetadata/Google/Protobuf/Duration.php \
GPBMetadata/Google/Protobuf/FieldMask.php \
GPBMetadata/Google/Protobuf/Struct.php \
GPBMetadata/Google/Protobuf/TestMessagesProto3.php \
GPBMetadata/Google/Protobuf/Timestamp.php \
GPBMetadata/Google/Protobuf/Wrappers.php \
Google/Protobuf/Any.php \
Google/Protobuf/BoolValue.php \
Google/Protobuf/BytesValue.php \
Google/Protobuf/DoubleValue.php \
Google/Protobuf/Duration.php \
Google/Protobuf/FieldMask.php \
Google/Protobuf/FloatValue.php \
Google/Protobuf/Int32Value.php \
Google/Protobuf/Int64Value.php \
Google/Protobuf/ListValue.php \
Google/Protobuf/NullValue.php \
Google/Protobuf/StringValue.php \
Google/Protobuf/Struct.php \
Google/Protobuf/Timestamp.php \
Google/Protobuf/UInt32Value.php \
Google/Protobuf/UInt64Value.php \
Google/Protobuf/Value.php \
Protobuf_test_messages/Proto3/ForeignEnum.php \
Protobuf_test_messages/Proto3/ForeignMessage.php \
Protobuf_test_messages/Proto3/TestAllTypes_NestedEnum.php \
Protobuf_test_messages/Proto3/TestAllTypes_NestedMessage.php \
Protobuf_test_messages/Proto3/TestAllTypes.php
# lite/com/google/protobuf/Any.java \
# lite/com/google/protobuf/AnyOrBuilder.java \
# lite/com/google/protobuf/AnyProto.java \
@ -146,14 +180,18 @@ EXTRA_DIST = \
conformance.proto \
conformance_python.py \
conformance_ruby.rb \
conformance_php.php \
failure_list_cpp.txt \
failure_list_csharp.txt \
failure_list_java.txt \
failure_list_js.txt \
failure_list_objc.txt \
failure_list_python.txt \
failure_list_python_cpp.txt \
failure_list_python-post26.txt \
failure_list_ruby.txt
failure_list_ruby.txt \
failure_list_php.txt \
failure_list_php_c.txt
conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
conformance_test_runner_SOURCES = conformance_test.h conformance_test.cc \
@ -194,12 +232,19 @@ conformance_objc-conformance_objc.$(OBJEXT): Conformance.pbobjc.h google/protobu
endif
# JavaScript well-known types are expected to be in a directory called
# google-protobuf, because they are usually in the google-protobuf npm
# package. But we want to use the sources from our tree, so we recreate
# that directory structure here.
google-protobuf:
mkdir google-protobuf
if USE_EXTERNAL_PROTOC
# Some implementations include pre-generated versions of well-known types.
protoc_middleman: $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs)
protoc_middleman: $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:. $(conformance_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:google-protobuf $(well_known_type_protoc_inputs)
## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
touch protoc_middleman
@ -208,9 +253,9 @@ else
# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
# relative to srcdir, which may not be the same as the current directory when
# building out-of-tree.
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) )
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd/google-protobuf $(well_known_type_protoc_inputs) )
## @mkdir -p lite
## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
touch protoc_middleman
@ -223,7 +268,7 @@ $(other_language_protoc_outputs): protoc_middleman
BUILT_SOURCES = $(protoc_outputs) $(other_language_protoc_outputs)
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java javac_middleman_lite conformance-java-lite conformance-csharp $(other_language_protoc_outputs)
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java javac_middleman_lite conformance-java-lite conformance-csharp conformance-php conformance-php-c $(other_language_protoc_outputs)
MAINTAINERCLEANFILES = \
Makefile.in
@ -257,6 +302,18 @@ conformance-csharp: $(other_language_protoc_outputs)
@echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp1.0/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp
@chmod +x conformance-csharp
conformance-php:
@echo "Writing shortcut script conformance-php..."
@echo '#! /bin/sh' > conformance-php
@echo 'php ./conformance_php.php' >> conformance-php
@chmod +x conformance-php
conformance-php-c:
@echo "Writing shortcut script conformance-php-c..."
@echo '#! /bin/sh' > conformance-php-c
@echo 'php -dextension=../php/ext/google/protobuf/modules/protobuf.so ./conformance_php.php' >> conformance-php-c
@chmod +x conformance-php-c
# Targets for actually running tests.
test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt ./conformance-cpp
@ -273,6 +330,12 @@ test_csharp: protoc_middleman conformance-test-runner conformance-csharp
test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_ruby.txt ./conformance_ruby.rb
test_php: protoc_middleman conformance-test-runner conformance-php $(other_language_protoc_outputs)
./conformance-test-runner --enforce_recommended --failure_list failure_list_php.txt ./conformance-php
test_php_c: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c.txt ./conformance-php-c
# These depend on library paths being properly set up. The easiest way to
# run them is to just use "tox" from the python dir.
test_python: protoc_middleman conformance-test-runner
@ -281,6 +344,9 @@ test_python: protoc_middleman conformance-test-runner
test_python_cpp: protoc_middleman conformance-test-runner
./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py
test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js
if OBJC_CONFORMANCE_TEST
test_objc: protoc_middleman conformance-test-runner conformance-objc

View file

@ -19,11 +19,39 @@ directory to build `protoc`, since all the tests depend on it.
$ make
Then to run the tests against the C++ implementation, run:
Running the tests for C++
-------------------------
To run the tests against the C++ implementation, run:
$ cd conformance && make test_cpp
More tests and languages will be added soon!
Running the tests for JavaScript (Node.js)
------------------------------------------
To run the JavaScript tests against Node.js, make sure you have "node"
on your path and then run:
$ cd conformance && make test_nodejs
Running the tests for Ruby (MRI)
--------------------------------
To run the Ruby tests against MRI, first build the C extension:
$ cd ruby && rake
Then run the tests like so:
$ cd conformance && make test_ruby
Running the tests for other languages
-------------------------------------
Most of the languages in the Protobuf source tree are set up to run
conformance tests. However some of them are more tricky to set up
properly. See `tests.sh` in the base of the repository to see how
Travis runs the tests.
Testing other Protocol Buffer implementations
---------------------------------------------

168
conformance/conformance_nodejs.js Executable file
View file

@ -0,0 +1,168 @@
#!/usr/bin/env node
/*
* Protocol Buffers - Google's data interchange format
* Copyright 2008 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.
*/
var conformance = require('conformance_pb');
var test_messages_proto3 = require('google/protobuf/test_messages_proto3_pb');
var fs = require('fs');
var testCount = 0;
function doTest(request) {
var testMessage;
var response = new conformance.ConformanceResponse();
try {
if (request.getRequestedOutputFormat() === conformance.WireFormat.JSON) {
response.setSkipped("JSON not supported.");
return response;
}
switch (request.getPayloadCase()) {
case conformance.ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD:
try {
testMessage = test_messages_proto3.TestAllTypes.deserializeBinary(
request.getProtobufPayload());
} catch (err) {
response.setParseError(err.toString());
return response;
}
case conformance.ConformanceRequest.PayloadCase.JSON_PAYLOAD:
response.setSkipped("JSON not supported.");
return response;
case conformance.ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET:
response.setRuntimeError("Request didn't have payload");
return response;
}
switch (request.getRequestedOutputFormat()) {
case conformance.WireFormat.UNSPECIFIED:
response.setRuntimeError("Unspecified output format");
return response;
case conformance.WireFormat.PROTOBUF:
response.setProtobufPayload(testMessage.serializeBinary());
case conformance.WireFormat.JSON:
response.setSkipped("JSON not supported.");
return response;
default:
throw "Request didn't have requested output format";
}
} catch (err) {
response.setRuntimeError(err.toString());
}
return response;
}
function onEof(totalRead) {
if (totalRead == 0) {
return undefined;
} else {
throw "conformance_nodejs: premature EOF on stdin.";
}
}
// Utility function to read a buffer of N bytes.
function readBuffer(bytes) {
var buf = new Buffer(bytes);
var totalRead = 0;
while (totalRead < bytes) {
var read = 0;
try {
read = fs.readSync(process.stdin.fd, buf, totalRead, bytes - totalRead);
} catch (e) {
if (e.code == 'EOF') {
return onEof(totalRead)
} else if (e.code == 'EAGAIN') {
} else {
throw "conformance_nodejs: Error reading from stdin." + e;
}
}
totalRead += read;
}
return buf;
}
function writeBuffer(buffer) {
var totalWritten = 0;
while (totalWritten < buffer.length) {
totalWritten += fs.writeSync(
process.stdout.fd, buffer, totalWritten, buffer.length - totalWritten);
}
}
// Returns true if the test ran successfully, false on legitimate EOF.
// If EOF is encountered in an unexpected place, raises IOError.
function doTestIo() {
var lengthBuf = readBuffer(4);
if (!lengthBuf) {
return false;
}
var length = lengthBuf.readInt32LE(0);
var serializedRequest = readBuffer(length);
if (!serializedRequest) {
throw "conformance_nodejs: Failed to read request.";
}
serializedRequest = new Uint8Array(serializedRequest);
var request =
conformance.ConformanceRequest.deserializeBinary(serializedRequest);
var response = doTest(request);
var serializedResponse = response.serializeBinary();
lengthBuf = new Buffer(4);
lengthBuf.writeInt32LE(serializedResponse.length, 0);
writeBuffer(lengthBuf);
writeBuffer(new Buffer(serializedResponse));
testCount += 1
return true;
}
while (true) {
if (!doTestIo()) {
console.error('conformance_nodejs: received EOF from test runner ' +
"after " + testCount + " tests, exiting")
break;
}
}

112
conformance/conformance_php.php Executable file
View file

@ -0,0 +1,112 @@
<?php
require_once("Conformance/WireFormat.php");
require_once("Conformance/ConformanceResponse.php");
require_once("Conformance/ConformanceRequest.php");
require_once("Google/Protobuf/Any.php");
require_once("Google/Protobuf/Duration.php");
require_once("Google/Protobuf/FieldMask.php");
require_once("Google/Protobuf/Struct.php");
require_once("Google/Protobuf/Value.php");
require_once("Google/Protobuf/ListValue.php");
require_once("Google/Protobuf/NullValue.php");
require_once("Google/Protobuf/Timestamp.php");
require_once("Google/Protobuf/DoubleValue.php");
require_once("Google/Protobuf/BytesValue.php");
require_once("Google/Protobuf/FloatValue.php");
require_once("Google/Protobuf/Int64Value.php");
require_once("Google/Protobuf/UInt32Value.php");
require_once("Google/Protobuf/BoolValue.php");
require_once("Google/Protobuf/DoubleValue.php");
require_once("Google/Protobuf/Int32Value.php");
require_once("Google/Protobuf/StringValue.php");
require_once("Google/Protobuf/UInt64Value.php");
require_once("Protobuf_test_messages/Proto3/ForeignMessage.php");
require_once("Protobuf_test_messages/Proto3/ForeignEnum.php");
require_once("Protobuf_test_messages/Proto3/TestAllTypes.php");
require_once("Protobuf_test_messages/Proto3/TestAllTypes_NestedMessage.php");
require_once("Protobuf_test_messages/Proto3/TestAllTypes_NestedEnum.php");
require_once("GPBMetadata/Conformance.php");
require_once("GPBMetadata/Google/Protobuf/Any.php");
require_once("GPBMetadata/Google/Protobuf/Duration.php");
require_once("GPBMetadata/Google/Protobuf/FieldMask.php");
require_once("GPBMetadata/Google/Protobuf/Struct.php");
require_once("GPBMetadata/Google/Protobuf/Timestamp.php");
require_once("GPBMetadata/Google/Protobuf/Wrappers.php");
require_once("GPBMetadata/Google/Protobuf/TestMessagesProto3.php");
use \Conformance\WireFormat;
$test_count = 0;
function doTest($request)
{
$test_message = new \Protobuf_test_messages\Proto3\TestAllTypes();
$response = new \Conformance\ConformanceResponse();
if ($request->getPayload() == "protobuf_payload") {
try {
$test_message->mergeFromString($request->getProtobufPayload());
} catch (Exception $e) {
$response->setParseError($e->getMessage());
return $response;
}
} elseif ($request->getPayload() == "json_payload") {
try {
$test_message->jsonDecode($request->getJsonPayload());
} catch (Exception $e) {
$response->setParseError($e->getMessage());
return $response;
}
} else {
trigger_error("Request didn't have payload.", E_USER_ERROR);
}
if ($request->getRequestedOutputFormat() == WireFormat::UNSPECIFIED) {
trigger_error("Unspecified output format.", E_USER_ERROR);
} elseif ($request->getRequestedOutputFormat() == WireFormat::PROTOBUF) {
$response->setProtobufPayload($test_message->serializeToString());
} elseif ($request->getRequestedOutputFormat() == WireFormat::JSON) {
$response->setJsonPayload($test_message->jsonEncode());
}
return $response;
}
function doTestIO()
{
$length_bytes = fread(STDIN, 4);
if (strlen($length_bytes) == 0) {
return false; # EOF
} elseif (strlen($length_bytes) != 4) {
trigger_error("I/O error", E_USER_ERROR);
}
$length = unpack("V", $length_bytes)[1];
$serialized_request = fread(STDIN, $length);
if (strlen($serialized_request) != $length) {
trigger_error("I/O error", E_USER_ERROR);
}
$request = new \Conformance\ConformanceRequest();
$request->mergeFromString($serialized_request);
$response = doTest($request);
$serialized_response = $response->serializeToString();
fwrite(STDOUT, pack("V", strlen($serialized_response)));
fwrite(STDOUT, $serialized_response);
$GLOBALS['test_count'] += 1;
return true;
}
while(true){
if (!doTestIO()) {
fprintf(STDERR,
"conformance_php: received EOF from test runner " +
"after %d tests, exiting\n", $test_count);
exit;
}
}

View file

@ -109,13 +109,18 @@ string cat(const string& a, const string& b,
// The maximum number of bytes that it takes to encode a 64-bit varint.
#define VARINT_MAX_LEN 10
size_t vencode64(uint64_t val, char *buf) {
size_t vencode64(uint64_t val, int over_encoded_bytes, char *buf) {
if (val == 0) { buf[0] = 0; return 1; }
size_t i = 0;
while (val) {
uint8_t byte = val & 0x7fU;
val >>= 7;
if (val) byte |= 0x80U;
if (val || over_encoded_bytes) byte |= 0x80U;
buf[i++] = byte;
}
while (over_encoded_bytes--) {
assert(i < 10);
uint8_t byte = over_encoded_bytes ? 0x80 : 0;
buf[i++] = byte;
}
return i;
@ -123,7 +128,15 @@ size_t vencode64(uint64_t val, char *buf) {
string varint(uint64_t x) {
char buf[VARINT_MAX_LEN];
size_t len = vencode64(x, buf);
size_t len = vencode64(x, 0, buf);
return string(buf, len);
}
// Encodes a varint that is |extra| bytes longer than it needs to be, but still
// valid.
string longvarint(uint64_t x, int extra) {
char buf[VARINT_MAX_LEN];
size_t len = vencode64(x, extra, buf);
return string(buf, len);
}
@ -695,6 +708,21 @@ bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
}
}
void ConformanceTestSuite::TestIllegalTags() {
// field num 0 is illegal
string nullfield[] = {
"\1DEADBEEF",
"\2\1\1",
"\3\4",
"\5DEAD"
};
for (int i = 0; i < 4; i++) {
string name = "IllegalZeroFieldNum_Case_0";
name.back() += i;
ExpectParseFailureForProto(nullfield[i], name, REQUIRED);
}
}
bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
std::string* output) {
runner_ = runner;
@ -715,6 +743,8 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
}
TestIllegalTags();
int64 kInt64Min = -9223372036854775808ULL;
int64 kInt64Max = 9223372036854775807ULL;
uint64 kUint64Max = 18446744073709551615ULL;
@ -744,13 +774,23 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
});
TestValidDataForType(FieldDescriptor::TYPE_INT32, {
{varint(12345), "12345"},
{longvarint(12345, 2), "12345"},
{longvarint(12345, 7), "12345"},
{varint(kInt32Max), std::to_string(kInt32Max)},
{varint(kInt32Min), std::to_string(kInt32Min)},
{varint(1LL << 33), std::to_string(static_cast<int32>(1LL << 33))},
{varint((1LL << 33) - 1),
std::to_string(static_cast<int32>((1LL << 33) - 1))},
});
TestValidDataForType(FieldDescriptor::TYPE_UINT32, {
{varint(12345), "12345"},
{longvarint(12345, 2), "12345"},
{longvarint(12345, 7), "12345"},
{varint(kUint32Max), std::to_string(kUint32Max)}, // UINT32_MAX
{varint(0), "0"}
{varint(0), "0"},
{varint(1LL << 33), std::to_string(static_cast<uint32>(1LL << 33))},
{varint((1LL << 33) - 1),
std::to_string(static_cast<uint32>((1LL << 33) - 1))},
});
TestValidDataForType(FieldDescriptor::TYPE_FIXED64, {
{u64(12345), "12345"},

View file

@ -201,6 +201,7 @@ class ConformanceTestSuite {
const std::string& test_name,
ConformanceLevel level);
void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
void TestIllegalTags();
void TestValidDataForType(
google::protobuf::FieldDescriptor::Type,
std::vector<std::pair<std::string, std::string>> values);

View file

@ -32,7 +32,6 @@ Recommended.JsonInput.TrailingCommaInAnObject
Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInPackedField.BOOL
@ -43,4 +42,3 @@ Required.ProtobufInput.PrematureEofInPackedField.SINT32
Required.ProtobufInput.PrematureEofInPackedField.SINT64
Required.ProtobufInput.PrematureEofInPackedField.UINT32
Required.ProtobufInput.PrematureEofInPackedField.UINT64
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE

View file

@ -0,0 +1,4 @@
Required.ProtobufInput.IllegalZeroFieldNum_Case_0
Required.ProtobufInput.IllegalZeroFieldNum_Case_1
Required.ProtobufInput.IllegalZeroFieldNum_Case_2
Required.ProtobufInput.IllegalZeroFieldNum_Case_3

View file

@ -0,0 +1,15 @@
Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput

View file

@ -1,4 +1,6 @@
# All tests currently passing.
#
# JSON input or output tests are skipped (in conformance_objc.m) as mobile
# platforms don't support JSON wire format to avoid code bloat.
Required.ProtobufInput.IllegalZeroFieldNum_Case_0
Required.ProtobufInput.IllegalZeroFieldNum_Case_1
Required.ProtobufInput.IllegalZeroFieldNum_Case_2
Required.ProtobufInput.IllegalZeroFieldNum_Case_3

View file

@ -0,0 +1,611 @@
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.JsonInput.BoolFieldAllCapitalFalse
Recommended.JsonInput.BoolFieldAllCapitalTrue
Recommended.JsonInput.BoolFieldCamelCaseFalse
Recommended.JsonInput.BoolFieldCamelCaseTrue
Recommended.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.JsonInput.BoolFieldIntegerOne
Recommended.JsonInput.BoolFieldIntegerZero
Recommended.JsonInput.BoolMapFieldKeyNotQuoted
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
Recommended.JsonInput.DoubleFieldNanNotQuoted
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
Recommended.JsonInput.DurationHas3FractionalDigits.Validator
Recommended.JsonInput.DurationHas6FractionalDigits.Validator
Recommended.JsonInput.DurationHas9FractionalDigits.Validator
Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
Recommended.JsonInput.FieldMaskInvalidCharacter
Recommended.JsonInput.FieldNameDuplicate
Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
Recommended.JsonInput.FieldNameNotQuoted
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
Recommended.JsonInput.FloatFieldInfinityNotQuoted
Recommended.JsonInput.FloatFieldNanNotQuoted
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
Recommended.JsonInput.Int32MapFieldKeyNotQuoted
Recommended.JsonInput.Int64FieldBeString.Validator
Recommended.JsonInput.Int64MapFieldKeyNotQuoted
Recommended.JsonInput.JsonWithComments
Recommended.JsonInput.MapFieldKeyIsNull
Recommended.JsonInput.MapFieldValueIsNull
Recommended.JsonInput.MissingCommaMultiline
Recommended.JsonInput.MissingCommaOneLine
Recommended.JsonInput.MultilineNoSpaces.JsonOutput
Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput
Recommended.JsonInput.MultilineWithSpaces.JsonOutput
Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput
Recommended.JsonInput.OneLineNoSpaces.JsonOutput
Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput
Recommended.JsonInput.OneLineWithSpaces.JsonOutput
Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput
Recommended.JsonInput.OneofZeroBool.JsonOutput
Recommended.JsonInput.OneofZeroBool.ProtobufOutput
Recommended.JsonInput.OneofZeroBytes.JsonOutput
Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
Recommended.JsonInput.OneofZeroDouble.JsonOutput
Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
Recommended.JsonInput.OneofZeroEnum.JsonOutput
Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
Recommended.JsonInput.OneofZeroFloat.JsonOutput
Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
Recommended.JsonInput.OneofZeroMessage.JsonOutput
Recommended.JsonInput.OneofZeroMessage.ProtobufOutput
Recommended.JsonInput.OneofZeroString.JsonOutput
Recommended.JsonInput.OneofZeroString.ProtobufOutput
Recommended.JsonInput.OneofZeroUint32.JsonOutput
Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
Recommended.JsonInput.OneofZeroUint64.JsonOutput
Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
Recommended.JsonInput.RepeatedFieldMessageElementIsNull
Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
Recommended.JsonInput.RepeatedFieldTrailingComma
Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
Recommended.JsonInput.StringEndsWithEscapeChar
Recommended.JsonInput.StringFieldInvalidEscape
Recommended.JsonInput.StringFieldSingleQuoteBoth
Recommended.JsonInput.StringFieldSingleQuoteKey
Recommended.JsonInput.StringFieldSingleQuoteValue
Recommended.JsonInput.StringFieldSurrogateInWrongOrder
Recommended.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.JsonInput.StringFieldUnterminatedEscape
Recommended.JsonInput.StringFieldUppercaseEscapeLetter
Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
Recommended.JsonInput.TimestampZeroNormalized.Validator
Recommended.JsonInput.TrailingCommaInAnObject
Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
Recommended.JsonInput.Uint64FieldBeString.Validator
Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
Recommended.ProtobufInput.OneofZeroBool.JsonOutput
Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
Recommended.ProtobufInput.OneofZeroMessage.JsonOutput
Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput
Recommended.ProtobufInput.OneofZeroString.JsonOutput
Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
Required.DurationProtoInputTooLarge.JsonOutput
Required.DurationProtoInputTooSmall.JsonOutput
Required.JsonInput.AllFieldAcceptNull.JsonOutput
Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
Required.JsonInput.Any.JsonOutput
Required.JsonInput.Any.ProtobufOutput
Required.JsonInput.AnyNested.JsonOutput
Required.JsonInput.AnyNested.ProtobufOutput
Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
Required.JsonInput.AnyWithDuration.JsonOutput
Required.JsonInput.AnyWithDuration.ProtobufOutput
Required.JsonInput.AnyWithFieldMask.JsonOutput
Required.JsonInput.AnyWithFieldMask.ProtobufOutput
Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
Required.JsonInput.AnyWithStruct.JsonOutput
Required.JsonInput.AnyWithStruct.ProtobufOutput
Required.JsonInput.AnyWithTimestamp.JsonOutput
Required.JsonInput.AnyWithTimestamp.ProtobufOutput
Required.JsonInput.AnyWithValueForInteger.JsonOutput
Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
Required.JsonInput.BoolFieldFalse.JsonOutput
Required.JsonInput.BoolFieldFalse.ProtobufOutput
Required.JsonInput.BoolFieldTrue.JsonOutput
Required.JsonInput.BoolFieldTrue.ProtobufOutput
Required.JsonInput.BoolMapEscapedKey.JsonOutput
Required.JsonInput.BoolMapEscapedKey.ProtobufOutput
Required.JsonInput.BoolMapField.JsonOutput
Required.JsonInput.BoolMapField.ProtobufOutput
Required.JsonInput.BytesField.JsonOutput
Required.JsonInput.BytesField.ProtobufOutput
Required.JsonInput.BytesFieldInvalidBase64Characters
Required.JsonInput.BytesRepeatedField.JsonOutput
Required.JsonInput.BytesRepeatedField.ProtobufOutput
Required.JsonInput.DoubleFieldInfinity.JsonOutput
Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
Required.JsonInput.DoubleFieldNan.JsonOutput
Required.JsonInput.DoubleFieldNan.ProtobufOutput
Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
Required.JsonInput.DoubleFieldTooLarge
Required.JsonInput.DoubleFieldTooSmall
Required.JsonInput.DurationJsonInputTooLarge
Required.JsonInput.DurationJsonInputTooSmall
Required.JsonInput.DurationMaxValue.JsonOutput
Required.JsonInput.DurationMaxValue.ProtobufOutput
Required.JsonInput.DurationMinValue.JsonOutput
Required.JsonInput.DurationMinValue.ProtobufOutput
Required.JsonInput.DurationMissingS
Required.JsonInput.DurationRepeatedValue.JsonOutput
Required.JsonInput.DurationRepeatedValue.ProtobufOutput
Required.JsonInput.EnumField.JsonOutput
Required.JsonInput.EnumField.ProtobufOutput
Required.JsonInput.EnumFieldNotQuoted
Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
Required.JsonInput.EnumFieldUnknownValue.Validator
Required.JsonInput.EnumRepeatedField.JsonOutput
Required.JsonInput.EnumRepeatedField.ProtobufOutput
Required.JsonInput.FieldMask.JsonOutput
Required.JsonInput.FieldMask.ProtobufOutput
Required.JsonInput.FieldNameEscaped.JsonOutput
Required.JsonInput.FieldNameEscaped.ProtobufOutput
Required.JsonInput.FieldNameInLowerCamelCase.Validator
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
Required.JsonInput.FieldNameWithMixedCases.JsonOutput
Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
Required.JsonInput.FieldNameWithMixedCases.Validator
Required.JsonInput.FieldNameWithNumbers.JsonOutput
Required.JsonInput.FieldNameWithNumbers.ProtobufOutput
Required.JsonInput.FieldNameWithNumbers.Validator
Required.JsonInput.FloatFieldInfinity.JsonOutput
Required.JsonInput.FloatFieldInfinity.ProtobufOutput
Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput
Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput
Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput
Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput
Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput
Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput
Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput
Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput
Required.JsonInput.FloatFieldNan.JsonOutput
Required.JsonInput.FloatFieldNan.ProtobufOutput
Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
Required.JsonInput.FloatFieldQuotedValue.JsonOutput
Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
Required.JsonInput.FloatFieldTooLarge
Required.JsonInput.FloatFieldTooSmall
Required.JsonInput.HelloWorld.JsonOutput
Required.JsonInput.HelloWorld.ProtobufOutput
Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
Required.JsonInput.Int32FieldLeadingSpace
Required.JsonInput.Int32FieldLeadingZero
Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
Required.JsonInput.Int32FieldMaxValue.JsonOutput
Required.JsonInput.Int32FieldMaxValue.ProtobufOutput
Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
Required.JsonInput.Int32FieldMinValue.JsonOutput
Required.JsonInput.Int32FieldMinValue.ProtobufOutput
Required.JsonInput.Int32FieldNegativeWithLeadingZero
Required.JsonInput.Int32FieldNotInteger
Required.JsonInput.Int32FieldNotNumber
Required.JsonInput.Int32FieldPlusSign
Required.JsonInput.Int32FieldStringValue.JsonOutput
Required.JsonInput.Int32FieldStringValue.ProtobufOutput
Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
Required.JsonInput.Int32FieldTooLarge
Required.JsonInput.Int32FieldTooSmall
Required.JsonInput.Int32FieldTrailingSpace
Required.JsonInput.Int32MapEscapedKey.JsonOutput
Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
Required.JsonInput.Int32MapField.JsonOutput
Required.JsonInput.Int32MapField.ProtobufOutput
Required.JsonInput.Int64FieldMaxValue.JsonOutput
Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
Required.JsonInput.Int64FieldMinValue.JsonOutput
Required.JsonInput.Int64FieldMinValue.ProtobufOutput
Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
Required.JsonInput.Int64FieldNotInteger
Required.JsonInput.Int64FieldNotNumber
Required.JsonInput.Int64FieldTooLarge
Required.JsonInput.Int64FieldTooSmall
Required.JsonInput.Int64MapEscapedKey.JsonOutput
Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
Required.JsonInput.Int64MapField.JsonOutput
Required.JsonInput.Int64MapField.ProtobufOutput
Required.JsonInput.MessageField.JsonOutput
Required.JsonInput.MessageField.ProtobufOutput
Required.JsonInput.MessageMapField.JsonOutput
Required.JsonInput.MessageMapField.ProtobufOutput
Required.JsonInput.MessageRepeatedField.JsonOutput
Required.JsonInput.MessageRepeatedField.ProtobufOutput
Required.JsonInput.OneofFieldDuplicate
Required.JsonInput.OptionalBoolWrapper.JsonOutput
Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
Required.JsonInput.OptionalBytesWrapper.JsonOutput
Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
Required.JsonInput.OptionalDoubleWrapper.JsonOutput
Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
Required.JsonInput.OptionalFloatWrapper.JsonOutput
Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
Required.JsonInput.OptionalInt32Wrapper.JsonOutput
Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
Required.JsonInput.OptionalInt64Wrapper.JsonOutput
Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
Required.JsonInput.OptionalStringWrapper.JsonOutput
Required.JsonInput.OptionalStringWrapper.ProtobufOutput
Required.JsonInput.OptionalUint32Wrapper.JsonOutput
Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
Required.JsonInput.OptionalUint64Wrapper.JsonOutput
Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
Required.JsonInput.OriginalProtoFieldName.JsonOutput
Required.JsonInput.OriginalProtoFieldName.ProtobufOutput
Required.JsonInput.PrimitiveRepeatedField.JsonOutput
Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
Required.JsonInput.RepeatedBoolWrapper.JsonOutput
Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
Required.JsonInput.RepeatedBytesWrapper.JsonOutput
Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage
Required.JsonInput.RepeatedFloatWrapper.JsonOutput
Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
Required.JsonInput.RepeatedStringWrapper.JsonOutput
Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
Required.JsonInput.StringField.JsonOutput
Required.JsonInput.StringField.ProtobufOutput
Required.JsonInput.StringFieldEscape.JsonOutput
Required.JsonInput.StringFieldEscape.ProtobufOutput
Required.JsonInput.StringFieldNotAString
Required.JsonInput.StringFieldSurrogatePair.JsonOutput
Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
Required.JsonInput.StringFieldUnicode.JsonOutput
Required.JsonInput.StringFieldUnicode.ProtobufOutput
Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
Required.JsonInput.StringRepeatedField.JsonOutput
Required.JsonInput.StringRepeatedField.ProtobufOutput
Required.JsonInput.Struct.JsonOutput
Required.JsonInput.Struct.ProtobufOutput
Required.JsonInput.TimestampJsonInputLowercaseT
Required.JsonInput.TimestampJsonInputLowercaseZ
Required.JsonInput.TimestampJsonInputMissingT
Required.JsonInput.TimestampJsonInputMissingZ
Required.JsonInput.TimestampJsonInputTooLarge
Required.JsonInput.TimestampJsonInputTooSmall
Required.JsonInput.TimestampMaxValue.JsonOutput
Required.JsonInput.TimestampMaxValue.ProtobufOutput
Required.JsonInput.TimestampMinValue.JsonOutput
Required.JsonInput.TimestampMinValue.ProtobufOutput
Required.JsonInput.TimestampRepeatedValue.JsonOutput
Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
Required.JsonInput.Uint32FieldMaxValue.JsonOutput
Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput
Required.JsonInput.Uint32FieldNotInteger
Required.JsonInput.Uint32FieldNotNumber
Required.JsonInput.Uint32FieldTooLarge
Required.JsonInput.Uint32MapField.JsonOutput
Required.JsonInput.Uint32MapField.ProtobufOutput
Required.JsonInput.Uint64FieldMaxValue.JsonOutput
Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
Required.JsonInput.Uint64FieldNotInteger
Required.JsonInput.Uint64FieldNotNumber
Required.JsonInput.Uint64FieldTooLarge
Required.JsonInput.Uint64MapField.JsonOutput
Required.JsonInput.Uint64MapField.ProtobufOutput
Required.JsonInput.ValueAcceptBool.JsonOutput
Required.JsonInput.ValueAcceptBool.ProtobufOutput
Required.JsonInput.ValueAcceptFloat.JsonOutput
Required.JsonInput.ValueAcceptFloat.ProtobufOutput
Required.JsonInput.ValueAcceptInteger.JsonOutput
Required.JsonInput.ValueAcceptInteger.ProtobufOutput
Required.JsonInput.ValueAcceptList.JsonOutput
Required.JsonInput.ValueAcceptList.ProtobufOutput
Required.JsonInput.ValueAcceptNull.JsonOutput
Required.JsonInput.ValueAcceptNull.ProtobufOutput
Required.JsonInput.ValueAcceptObject.JsonOutput
Required.JsonInput.ValueAcceptObject.ProtobufOutput
Required.JsonInput.ValueAcceptString.JsonOutput
Required.JsonInput.ValueAcceptString.ProtobufOutput
Required.JsonInput.WrapperTypesWithNullValue.JsonOutput
Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64
Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL
Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES
Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32
Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64
Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64
Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING
Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32
Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
Required.ProtobufInput.PrematureEofInPackedField.BOOL
Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
Required.ProtobufInput.PrematureEofInPackedField.ENUM
Required.ProtobufInput.PrematureEofInPackedField.FIXED32
Required.ProtobufInput.PrematureEofInPackedField.FIXED64
Required.ProtobufInput.PrematureEofInPackedField.FLOAT
Required.ProtobufInput.PrematureEofInPackedField.INT32
Required.ProtobufInput.PrematureEofInPackedField.INT64
Required.ProtobufInput.PrematureEofInPackedField.SFIXED32
Required.ProtobufInput.PrematureEofInPackedField.SFIXED64
Required.ProtobufInput.PrematureEofInPackedField.SINT32
Required.ProtobufInput.PrematureEofInPackedField.SINT64
Required.ProtobufInput.PrematureEofInPackedField.UINT32
Required.ProtobufInput.PrematureEofInPackedField.UINT64
Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL
Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE
Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM
Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32
Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64
Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT
Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32
Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64
Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32
Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64
Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32
Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64
Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32
Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64
Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64
Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL
Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES
Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM
Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32
Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64
Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE
Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64
Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32
Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64
Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING
Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32
Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64
Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput
Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput
Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput
Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput
Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput
Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput
Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput
Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput
Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput
Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput
Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput
Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput
Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput
Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput
Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput
Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput
Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput
Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput
Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput
Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput
Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput
Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput
Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput
Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput
Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput
Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput
Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput
Required.TimestampProtoInputTooLarge.JsonOutput
Required.TimestampProtoInputTooSmall.JsonOutput

View file

@ -0,0 +1,227 @@
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.JsonInput.BoolFieldIntegerOne
Recommended.JsonInput.BoolFieldIntegerZero
Recommended.JsonInput.DurationHas3FractionalDigits.Validator
Recommended.JsonInput.DurationHas6FractionalDigits.Validator
Recommended.JsonInput.DurationHas9FractionalDigits.Validator
Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
Recommended.JsonInput.Int64FieldBeString.Validator
Recommended.JsonInput.MapFieldValueIsNull
Recommended.JsonInput.OneofZeroBool.JsonOutput
Recommended.JsonInput.OneofZeroBool.ProtobufOutput
Recommended.JsonInput.OneofZeroBytes.JsonOutput
Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
Recommended.JsonInput.OneofZeroDouble.JsonOutput
Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
Recommended.JsonInput.OneofZeroEnum.JsonOutput
Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
Recommended.JsonInput.OneofZeroFloat.JsonOutput
Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
Recommended.JsonInput.OneofZeroString.JsonOutput
Recommended.JsonInput.OneofZeroString.ProtobufOutput
Recommended.JsonInput.OneofZeroUint32.JsonOutput
Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
Recommended.JsonInput.OneofZeroUint64.JsonOutput
Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
Recommended.JsonInput.RepeatedFieldMessageElementIsNull
Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
Recommended.JsonInput.StringEndsWithEscapeChar
Recommended.JsonInput.StringFieldSurrogateInWrongOrder
Recommended.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
Recommended.JsonInput.TimestampZeroNormalized.Validator
Recommended.JsonInput.Uint64FieldBeString.Validator
Recommended.ProtobufInput.OneofZeroBool.JsonOutput
Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
Recommended.ProtobufInput.OneofZeroString.JsonOutput
Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
Required.DurationProtoInputTooLarge.JsonOutput
Required.DurationProtoInputTooSmall.JsonOutput
Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
Required.JsonInput.Any.JsonOutput
Required.JsonInput.Any.ProtobufOutput
Required.JsonInput.AnyNested.JsonOutput
Required.JsonInput.AnyNested.ProtobufOutput
Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
Required.JsonInput.AnyWithDuration.JsonOutput
Required.JsonInput.AnyWithDuration.ProtobufOutput
Required.JsonInput.AnyWithFieldMask.JsonOutput
Required.JsonInput.AnyWithFieldMask.ProtobufOutput
Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
Required.JsonInput.AnyWithStruct.JsonOutput
Required.JsonInput.AnyWithStruct.ProtobufOutput
Required.JsonInput.AnyWithTimestamp.JsonOutput
Required.JsonInput.AnyWithTimestamp.ProtobufOutput
Required.JsonInput.AnyWithValueForInteger.JsonOutput
Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
Required.JsonInput.BoolFieldFalse.ProtobufOutput
Required.JsonInput.BoolMapField.JsonOutput
Required.JsonInput.DoubleFieldInfinity.JsonOutput
Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
Required.JsonInput.DoubleFieldNan.JsonOutput
Required.JsonInput.DoubleFieldNan.ProtobufOutput
Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
Required.JsonInput.DurationMaxValue.JsonOutput
Required.JsonInput.DurationMaxValue.ProtobufOutput
Required.JsonInput.DurationMinValue.JsonOutput
Required.JsonInput.DurationMinValue.ProtobufOutput
Required.JsonInput.DurationRepeatedValue.JsonOutput
Required.JsonInput.DurationRepeatedValue.ProtobufOutput
Required.JsonInput.EnumField.ProtobufOutput
Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
Required.JsonInput.EnumFieldUnknownValue.Validator
Required.JsonInput.FieldMask.JsonOutput
Required.JsonInput.FieldMask.ProtobufOutput
Required.JsonInput.FloatFieldInfinity.JsonOutput
Required.JsonInput.FloatFieldInfinity.ProtobufOutput
Required.JsonInput.FloatFieldNan.JsonOutput
Required.JsonInput.FloatFieldNan.ProtobufOutput
Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
Required.JsonInput.FloatFieldQuotedValue.JsonOutput
Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
Required.JsonInput.FloatFieldTooLarge
Required.JsonInput.FloatFieldTooSmall
Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
Required.JsonInput.Int32FieldStringValue.JsonOutput
Required.JsonInput.Int32FieldStringValue.ProtobufOutput
Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
Required.JsonInput.Int64FieldMaxValue.JsonOutput
Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
Required.JsonInput.Int64FieldMinValue.JsonOutput
Required.JsonInput.Int64FieldMinValue.ProtobufOutput
Required.JsonInput.MessageField.JsonOutput
Required.JsonInput.MessageField.ProtobufOutput
Required.JsonInput.OptionalBoolWrapper.JsonOutput
Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
Required.JsonInput.OptionalBytesWrapper.JsonOutput
Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
Required.JsonInput.OptionalDoubleWrapper.JsonOutput
Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
Required.JsonInput.OptionalFloatWrapper.JsonOutput
Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
Required.JsonInput.OptionalInt32Wrapper.JsonOutput
Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
Required.JsonInput.OptionalInt64Wrapper.JsonOutput
Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
Required.JsonInput.OptionalStringWrapper.JsonOutput
Required.JsonInput.OptionalStringWrapper.ProtobufOutput
Required.JsonInput.OptionalUint32Wrapper.JsonOutput
Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
Required.JsonInput.OptionalUint64Wrapper.JsonOutput
Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
Required.JsonInput.RepeatedBoolWrapper.JsonOutput
Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
Required.JsonInput.RepeatedBytesWrapper.JsonOutput
Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.JsonInput.RepeatedFloatWrapper.JsonOutput
Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
Required.JsonInput.RepeatedStringWrapper.JsonOutput
Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
Required.JsonInput.StringFieldEscape.JsonOutput
Required.JsonInput.StringFieldEscape.ProtobufOutput
Required.JsonInput.StringFieldNotAString
Required.JsonInput.StringFieldSurrogatePair.JsonOutput
Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
Required.JsonInput.Struct.JsonOutput
Required.JsonInput.Struct.ProtobufOutput
Required.JsonInput.TimestampMaxValue.JsonOutput
Required.JsonInput.TimestampMaxValue.ProtobufOutput
Required.JsonInput.TimestampMinValue.JsonOutput
Required.JsonInput.TimestampMinValue.ProtobufOutput
Required.JsonInput.TimestampRepeatedValue.JsonOutput
Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
Required.JsonInput.Uint64FieldMaxValue.JsonOutput
Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
Required.JsonInput.ValueAcceptBool.JsonOutput
Required.JsonInput.ValueAcceptBool.ProtobufOutput
Required.JsonInput.ValueAcceptFloat.JsonOutput
Required.JsonInput.ValueAcceptFloat.ProtobufOutput
Required.JsonInput.ValueAcceptInteger.JsonOutput
Required.JsonInput.ValueAcceptInteger.ProtobufOutput
Required.JsonInput.ValueAcceptList.JsonOutput
Required.JsonInput.ValueAcceptList.ProtobufOutput
Required.JsonInput.ValueAcceptNull.JsonOutput
Required.JsonInput.ValueAcceptNull.ProtobufOutput
Required.JsonInput.ValueAcceptObject.JsonOutput
Required.JsonInput.ValueAcceptObject.ProtobufOutput
Required.JsonInput.ValueAcceptString.JsonOutput
Required.JsonInput.ValueAcceptString.ProtobufOutput
Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
Required.TimestampProtoInputTooLarge.JsonOutput
Required.TimestampProtoInputTooSmall.JsonOutput

View file

@ -11,3 +11,7 @@ Required.JsonInput.FloatFieldTooLarge
Required.JsonInput.FloatFieldTooSmall
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
Required.JsonInput.TimestampJsonInputLowercaseT
Required.ProtobufInput.IllegalZeroFieldNum_Case_0
Required.ProtobufInput.IllegalZeroFieldNum_Case_1
Required.ProtobufInput.IllegalZeroFieldNum_Case_2
Required.ProtobufInput.IllegalZeroFieldNum_Case_3

View file

@ -57,7 +57,7 @@ for remove_file in (args.remove_list or []):
with open(remove_file) as f:
for line in f:
if line in add_set:
raise "Asked to both add and remove test: " + line
raise Exception("Asked to both add and remove test: " + line)
remove_set.add(line.strip())
add_list = sorted(add_set, reverse=True)

View file

@ -5,7 +5,7 @@
<title>Google Protocol Buffers tools</title>
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
<description>See project site for more info.</description>
<version>3.2.0</version>
<version>3.3.0</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl>

View file

@ -32,8 +32,7 @@ Building
========
Open the `src/Google.Protobuf.sln` solution in Visual Studio 2015 or
later. You should be able to run the NUnit test from Test Explorer
(you might need to install NUnit Visual Studio add-in).
later.
Although *users* of this project are only expected to have Visual
Studio 2012 or later, *developers* of the library are required to
@ -42,6 +41,57 @@ in its implementation. These features have no impact when using the
compiled code - they're only relevant when building the
`Google.Protobuf` assembly.
Testing
=======
The unit tests use [NUnit 3](https://github.com/nunit/nunit). Vanilla NUnit doesn't
support .NET Core, so to run the tests you'll need to use
[dotnet-test-nunit](https://github.com/nunit/dotnet-test-nunit).
`dotnet-test-nunit` can also run tests for .NET 4.5+, so to run the tests
for both .NET Core and .NET 4.5, you can simply open the
`Package Manager Console` in Visual Studio and execute:
```
dotnet test Google.Protobuf.Test
```
.NET 3.5
========
We don't officially support .NET 3.5. However, there has been some effort
to make enabling .NET 3.5 support relatively painless in case you require it.
There's no guarantee that this will continue in the future, so rely on .NET
3.5 support at your peril.
To enable .NET 3.5 support:
1. Modify [src/Google.Protobuf/project.json](src/Google.Protobuf/project.json) to add `"net35": {}` to `"frameworks"`.
2. Modify [src/Google.Protobuf.Test/project.json](src/Google.Protobuf/project.json):
1. Add `"net35": {}` to `"frameworks"`.
2. `dotnet-test-nunit` doesn't support .NET 3.5, so remove it from
the project-wide `"dependencies"` and add it to the framework-specific
dependencies under `"net451"` and `"netcoreapp1.0"`.
Note that `dotnet-test-nunit` doesn't support .NET 3.5. You can instead run the
tests with [NUnit 3 console](https://github.com/nunit/nunit-console)
by running something like:
```
nunit3-console.exe "Google.Protobuf.Test\bin\Debug\net35\win7-x64\Google.Protobuf.Test.dll" --inprocess
```
The exact path may differ depending on your environment (e.g., the `win7-x64`
directory may be called something else). The `--inprocess` flag seems to be a
necessary workaround for a bug in NUnit; otherwise, you'll receive
an error "Exception has been thrown by the target of an invocation"
([possibly related issue](https://github.com/nunit/nunit/issues/1480)).
If you still want to run the .NET 4.5 and .NET Core tests, you can do so by
specifying the framework when using `dotnet-test-nunit`, i.e. from
`Package Manager Console` in Visual Studio:
```
dotnet test Google.Protobuf.Test --framework netcoreapp1.0
dotnet test Google.Protobuf.Test --framework net451
```
History of C# protobufs
=======================

View file

@ -0,0 +1,126 @@
syntax = "proto3";
// These proto descriptors have at one time been reported as an issue or defect.
// They are kept here to replicate the issue, and continue to verify the fix.
// Issue: Non-"Google.Protobuffers" namespace will ensure that protobuffer library types are qualified
option csharp_namespace = "UnitTest.Issues.TestProtos";
package unittest_issues;
option optimize_for = SPEED;
// Issue 307: when generating doubly-nested types, any references
// should be of the form A.Types.B.Types.C.
message Issue307 {
message NestedOnce {
message NestedTwice {
}
}
}
// Old issue 13: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=13
// New issue 309: https://github.com/google/protobuf/issues/309
// message A {
// optional int32 _A = 1;
// }
// message B {
// optional int32 B_ = 1;
// }
//message AB {
// optional int32 a_b = 1;
//}
// Similar issue with numeric names
// Java code failed too, so probably best for this to be a restriction.
// See https://github.com/google/protobuf/issues/308
// message NumberField {
// optional int32 _01 = 1;
// }
// issue 19 - negative enum values
enum NegativeEnum {
NEGATIVE_ENUM_ZERO = 0;
FiveBelow = -5;
MinusOne = -1;
}
message NegativeEnumMessage {
NegativeEnum value = 1;
repeated NegativeEnum values = 2 [packed = false];
repeated NegativeEnum packed_values = 3 [packed=true];
}
// Issue 21: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=21
// Decorate fields with [deprecated=true] as [System.Obsolete]
message DeprecatedChild {
}
enum DeprecatedEnum {
DEPRECATED_ZERO = 0;
one = 1;
}
message DeprecatedFieldsMessage {
int32 PrimitiveValue = 1 [deprecated = true];
repeated int32 PrimitiveArray = 2 [deprecated = true];
DeprecatedChild MessageValue = 3 [deprecated = true];
repeated DeprecatedChild MessageArray = 4 [deprecated = true];
DeprecatedEnum EnumValue = 5 [deprecated = true];
repeated DeprecatedEnum EnumArray = 6 [deprecated = true];
}
// Issue 45: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=45
message ItemField {
int32 item = 1;
}
message ReservedNames {
// Force a nested type called Types
message SomeNestedType {
}
int32 types = 1;
int32 descriptor = 2;
}
message TestJsonFieldOrdering {
// These fields are deliberately not declared in numeric
// order, and the oneof fields aren't contiguous either.
// This allows for reasonably robust tests of JSON output
// ordering.
// TestFieldOrderings in unittest_proto3.proto is similar,
// but doesn't include oneofs.
// TODO: Consider adding oneofs to TestFieldOrderings, although
// that will require fixing other tests in multiple platforms.
// Alternatively, consider just adding this to
// unittest_proto3.proto if multiple platforms want it.
int32 plain_int32 = 4;
oneof o1 {
string o1_string = 2;
int32 o1_int32 = 5;
}
string plain_string = 1;
oneof o2 {
int32 o2_int32 = 6;
string o2_string = 3;
}
}
message TestJsonName {
// Message for testing the effects for of the json_name option
string name = 1;
string description = 2 [json_name = "desc"];
string guid = 3 [json_name = "exid"];
}

View file

@ -0,0 +1,120 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.
// This file is mostly equivalent to map_unittest.proto, but imports
// unittest_proto3.proto instead of unittest.proto, so that it only
// uses proto3 messages. This makes it suitable for testing
// implementations which only support proto3.
// The TestRequiredMessageMap message has been removed as there are no
// required fields in proto3.
syntax = "proto3";
option cc_enable_arenas = true;
option csharp_namespace = "Google.Protobuf.TestProtos";
import "google/protobuf/unittest_proto3.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In map_test_util.h we do "using namespace unittest = protobuf_unittest".
package protobuf_unittest;
// Tests maps.
message TestMap {
map<int32 , int32 > map_int32_int32 = 1;
map<int64 , int64 > map_int64_int64 = 2;
map<uint32 , uint32 > map_uint32_uint32 = 3;
map<uint64 , uint64 > map_uint64_uint64 = 4;
map<sint32 , sint32 > map_sint32_sint32 = 5;
map<sint64 , sint64 > map_sint64_sint64 = 6;
map<fixed32 , fixed32 > map_fixed32_fixed32 = 7;
map<fixed64 , fixed64 > map_fixed64_fixed64 = 8;
map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
map<int32 , float > map_int32_float = 11;
map<int32 , double > map_int32_double = 12;
map<bool , bool > map_bool_bool = 13;
map<string , string > map_string_string = 14;
map<int32 , bytes > map_int32_bytes = 15;
map<int32 , MapEnum > map_int32_enum = 16;
map<int32 , ForeignMessage> map_int32_foreign_message = 17;
}
message TestMapSubmessage {
TestMap test_map = 1;
}
message TestMessageMap {
map<int32, TestAllTypes> map_int32_message = 1;
}
// Two map fields share the same entry default instance.
message TestSameTypeMap {
map<int32, int32> map1 = 1;
map<int32, int32> map2 = 2;
}
enum MapEnum {
MAP_ENUM_FOO = 0;
MAP_ENUM_BAR = 1;
MAP_ENUM_BAZ = 2;
}
message TestArenaMap {
map<int32 , int32 > map_int32_int32 = 1;
map<int64 , int64 > map_int64_int64 = 2;
map<uint32 , uint32 > map_uint32_uint32 = 3;
map<uint64 , uint64 > map_uint64_uint64 = 4;
map<sint32 , sint32 > map_sint32_sint32 = 5;
map<sint64 , sint64 > map_sint64_sint64 = 6;
map<fixed32 , fixed32 > map_fixed32_fixed32 = 7;
map<fixed64 , fixed64 > map_fixed64_fixed64 = 8;
map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
map<int32 , float > map_int32_float = 11;
map<int32 , double > map_int32_double = 12;
map<bool , bool > map_bool_bool = 13;
map<int32 , MapEnum > map_int32_enum = 14;
map<int32 , ForeignMessage> map_int32_foreign_message = 15;
}
// Previously, message containing enum called Type cannot be used as value of
// map field.
message MessageContainingEnumCalledType {
enum Type {
TYPE_FOO = 0;
}
map<int32, MessageContainingEnumCalledType> type = 1;
}
// Previously, message cannot contain map field called "entry".
message MessageContainingMapCalledEntry {
map<int32, int32> entry = 1;
}

View file

@ -0,0 +1,68 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// A proto file which is imported by unittest_proto3.proto to test importing.
syntax = "proto3";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In test_util.h we do
// "using namespace unittest_import = protobuf_unittest_import".
package protobuf_unittest_import;
option optimize_for = SPEED;
option cc_enable_arenas = true;
// Exercise the java_package option.
option java_package = "com.google.protobuf.test";
option csharp_namespace = "Google.Protobuf.TestProtos";
// Do not set a java_outer_classname here to verify that Proto2 works without
// one.
// Test public import
import public "google/protobuf/unittest_import_public_proto3.proto";
message ImportMessage {
int32 d = 1;
}
enum ImportEnum {
IMPORT_ENUM_UNSPECIFIED = 0;
IMPORT_FOO = 7;
IMPORT_BAR = 8;
IMPORT_BAZ = 9;
}

View file

@ -28,18 +28,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Negative compilation test for arena usage.
// Author: liujisi@google.com (Pherl Liu)
#include <google/protobuf/arena.h>
#include <google/protobuf/unittest.pb.h>
syntax = "proto3";
#ifdef TEST_ARENA_PRIVATE_CONSTRUCTOR
package protobuf_unittest_import;
namespace google {
void ArenaPrivateConstructor() {
google::protobuf::Arena arena;
protobuf_unittest::TestAllTypes message(&arena);
option java_package = "com.google.protobuf.test";
option csharp_namespace = "Google.Protobuf.TestProtos";
message PublicImportMessage {
int32 e = 1;
}
#endif
} // namespace google

View file

@ -0,0 +1,388 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// A proto file we will use for unit testing.
syntax = "proto3";
// Some generic_services option(s) added automatically.
// See: http://go/proto2-generic-services-default
option cc_generic_services = true; // auto-added
option java_generic_services = true; // auto-added
option py_generic_services = true; // auto-added
option cc_enable_arenas = true;
option csharp_namespace = "Google.Protobuf.TestProtos";
import "google/protobuf/unittest_import_proto3.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In test_util.h we do "using namespace unittest = protobuf_unittest".
package protobuf_unittest;
// Protos optimized for SPEED use a strict superset of the generated code
// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
// tests for speed unless explicitly testing code size optimization.
option optimize_for = SPEED;
option java_outer_classname = "UnittestProto";
// This proto includes every type of field in both singular and repeated
// forms.
message TestAllTypes {
message NestedMessage {
// The field name "b" fails to compile in proto1 because it conflicts with
// a local variable named "b" in one of the generated methods. Doh.
// This file needs to compile in proto1 to test backwards-compatibility.
int32 bb = 1;
}
enum NestedEnum {
NESTED_ENUM_UNSPECIFIED = 0;
FOO = 1;
BAR = 2;
BAZ = 3;
NEG = -1; // Intentionally negative.
}
// Singular
int32 single_int32 = 1;
int64 single_int64 = 2;
uint32 single_uint32 = 3;
uint64 single_uint64 = 4;
sint32 single_sint32 = 5;
sint64 single_sint64 = 6;
fixed32 single_fixed32 = 7;
fixed64 single_fixed64 = 8;
sfixed32 single_sfixed32 = 9;
sfixed64 single_sfixed64 = 10;
float single_float = 11;
double single_double = 12;
bool single_bool = 13;
string single_string = 14;
bytes single_bytes = 15;
NestedMessage single_nested_message = 18;
ForeignMessage single_foreign_message = 19;
protobuf_unittest_import.ImportMessage single_import_message = 20;
NestedEnum single_nested_enum = 21;
ForeignEnum single_foreign_enum = 22;
protobuf_unittest_import.ImportEnum single_import_enum = 23;
// Defined in unittest_import_public.proto
protobuf_unittest_import.PublicImportMessage
single_public_import_message = 26;
// Repeated
repeated int32 repeated_int32 = 31;
repeated int64 repeated_int64 = 32;
repeated uint32 repeated_uint32 = 33;
repeated uint64 repeated_uint64 = 34;
repeated sint32 repeated_sint32 = 35;
repeated sint64 repeated_sint64 = 36;
repeated fixed32 repeated_fixed32 = 37;
repeated fixed64 repeated_fixed64 = 38;
repeated sfixed32 repeated_sfixed32 = 39;
repeated sfixed64 repeated_sfixed64 = 40;
repeated float repeated_float = 41;
repeated double repeated_double = 42;
repeated bool repeated_bool = 43;
repeated string repeated_string = 44;
repeated bytes repeated_bytes = 45;
repeated NestedMessage repeated_nested_message = 48;
repeated ForeignMessage repeated_foreign_message = 49;
repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
repeated NestedEnum repeated_nested_enum = 51;
repeated ForeignEnum repeated_foreign_enum = 52;
repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
// Defined in unittest_import_public.proto
repeated protobuf_unittest_import.PublicImportMessage
repeated_public_import_message = 54;
// For oneof test
oneof oneof_field {
uint32 oneof_uint32 = 111;
NestedMessage oneof_nested_message = 112;
string oneof_string = 113;
bytes oneof_bytes = 114;
}
}
// This proto includes a recusively nested message.
message NestedTestAllTypes {
NestedTestAllTypes child = 1;
TestAllTypes payload = 2;
repeated NestedTestAllTypes repeated_child = 3;
}
message TestDeprecatedFields {
int32 deprecated_int32 = 1 [deprecated=true];
}
// Define these after TestAllTypes to make sure the compiler can handle
// that.
message ForeignMessage {
int32 c = 1;
}
enum ForeignEnum {
FOREIGN_UNSPECIFIED = 0;
FOREIGN_FOO = 4;
FOREIGN_BAR = 5;
FOREIGN_BAZ = 6;
}
message TestReservedFields {
reserved 2, 15, 9 to 11;
reserved "bar", "baz";
}
// Test that we can use NestedMessage from outside TestAllTypes.
message TestForeignNested {
TestAllTypes.NestedMessage foreign_nested = 1;
}
// Test that really large tag numbers don't break anything.
message TestReallyLargeTagNumber {
// The largest possible tag number is 2^28 - 1, since the wire format uses
// three bits to communicate wire type.
int32 a = 1;
int32 bb = 268435455;
}
message TestRecursiveMessage {
TestRecursiveMessage a = 1;
int32 i = 2;
}
// Test that mutual recursion works.
message TestMutualRecursionA {
TestMutualRecursionB bb = 1;
}
message TestMutualRecursionB {
TestMutualRecursionA a = 1;
int32 optional_int32 = 2;
}
// Test an enum that has multiple values with the same number.
enum TestEnumWithDupValue {
TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0;
option allow_alias = true;
FOO1 = 1;
BAR1 = 2;
BAZ = 3;
FOO2 = 1;
BAR2 = 2;
}
// Test an enum with large, unordered values.
enum TestSparseEnum {
TEST_SPARSE_ENUM_UNSPECIFIED = 0;
SPARSE_A = 123;
SPARSE_B = 62374;
SPARSE_C = 12589234;
SPARSE_D = -15;
SPARSE_E = -53452;
// In proto3, value 0 must be the first one specified
// SPARSE_F = 0;
SPARSE_G = 2;
}
// Test message with CamelCase field names. This violates Protocol Buffer
// standard style.
message TestCamelCaseFieldNames {
int32 PrimitiveField = 1;
string StringField = 2;
ForeignEnum EnumField = 3;
ForeignMessage MessageField = 4;
repeated int32 RepeatedPrimitiveField = 7;
repeated string RepeatedStringField = 8;
repeated ForeignEnum RepeatedEnumField = 9;
repeated ForeignMessage RepeatedMessageField = 10;
}
// We list fields out of order, to ensure that we're using field number and not
// field index to determine serialization order.
message TestFieldOrderings {
string my_string = 11;
int64 my_int = 1;
float my_float = 101;
message NestedMessage {
int64 oo = 2;
// The field name "b" fails to compile in proto1 because it conflicts with
// a local variable named "b" in one of the generated methods. Doh.
// This file needs to compile in proto1 to test backwards-compatibility.
int32 bb = 1;
}
NestedMessage single_nested_message = 200;
}
message SparseEnumMessage {
TestSparseEnum sparse_enum = 1;
}
// Test String and Bytes: string is for valid UTF-8 strings
message OneString {
string data = 1;
}
message MoreString {
repeated string data = 1;
}
message OneBytes {
bytes data = 1;
}
message MoreBytes {
bytes data = 1;
}
// Test int32, uint32, int64, uint64, and bool are all compatible
message Int32Message {
int32 data = 1;
}
message Uint32Message {
uint32 data = 1;
}
message Int64Message {
int64 data = 1;
}
message Uint64Message {
uint64 data = 1;
}
message BoolMessage {
bool data = 1;
}
// Test oneofs.
message TestOneof {
oneof foo {
int32 foo_int = 1;
string foo_string = 2;
TestAllTypes foo_message = 3;
}
}
// Test messages for packed fields
message TestPackedTypes {
repeated int32 packed_int32 = 90 [packed = true];
repeated int64 packed_int64 = 91 [packed = true];
repeated uint32 packed_uint32 = 92 [packed = true];
repeated uint64 packed_uint64 = 93 [packed = true];
repeated sint32 packed_sint32 = 94 [packed = true];
repeated sint64 packed_sint64 = 95 [packed = true];
repeated fixed32 packed_fixed32 = 96 [packed = true];
repeated fixed64 packed_fixed64 = 97 [packed = true];
repeated sfixed32 packed_sfixed32 = 98 [packed = true];
repeated sfixed64 packed_sfixed64 = 99 [packed = true];
repeated float packed_float = 100 [packed = true];
repeated double packed_double = 101 [packed = true];
repeated bool packed_bool = 102 [packed = true];
repeated ForeignEnum packed_enum = 103 [packed = true];
}
// A message with the same fields as TestPackedTypes, but without packing. Used
// to test packed <-> unpacked wire compatibility.
message TestUnpackedTypes {
repeated int32 unpacked_int32 = 90 [packed = false];
repeated int64 unpacked_int64 = 91 [packed = false];
repeated uint32 unpacked_uint32 = 92 [packed = false];
repeated uint64 unpacked_uint64 = 93 [packed = false];
repeated sint32 unpacked_sint32 = 94 [packed = false];
repeated sint64 unpacked_sint64 = 95 [packed = false];
repeated fixed32 unpacked_fixed32 = 96 [packed = false];
repeated fixed64 unpacked_fixed64 = 97 [packed = false];
repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];
repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];
repeated float unpacked_float = 100 [packed = false];
repeated double unpacked_double = 101 [packed = false];
repeated bool unpacked_bool = 102 [packed = false];
repeated ForeignEnum unpacked_enum = 103 [packed = false];
}
message TestRepeatedScalarDifferentTagSizes {
// Parsing repeated fixed size values used to fail. This message needs to be
// used in order to get a tag of the right size; all of the repeated fields
// in TestAllTypes didn't trigger the check.
repeated fixed32 repeated_fixed32 = 12;
// Check for a varint type, just for good measure.
repeated int32 repeated_int32 = 13;
// These have two-byte tags.
repeated fixed64 repeated_fixed64 = 2046;
repeated int64 repeated_int64 = 2047;
// Three byte tags.
repeated float repeated_float = 262142;
repeated uint64 repeated_uint64 = 262143;
}
message TestCommentInjectionMessage {
// */ <- This should not close the generated doc comment
string a = 1;
}
// Test that RPC services work.
message FooRequest {}
message FooResponse {}
message FooClientMessage {}
message FooServerMessage{}
service TestService {
rpc Foo(FooRequest) returns (FooResponse);
rpc Bar(BarRequest) returns (BarResponse);
}
message BarRequest {}
message BarResponse {}

View file

@ -0,0 +1,114 @@
syntax = "proto3";
package protobuf_unittest;
option csharp_namespace = "Google.Protobuf.TestProtos";
option java_multiple_files = true;
option java_package = "com.google.protobuf.test";
import "google/protobuf/any.proto";
import "google/protobuf/api.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/source_context.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/type.proto";
import "google/protobuf/wrappers.proto";
// Test that we can include all well-known types.
// Each wrapper type is included separately, as languages
// map handle different wrappers in different ways.
message TestWellKnownTypes {
google.protobuf.Any any_field = 1;
google.protobuf.Api api_field = 2;
google.protobuf.Duration duration_field = 3;
google.protobuf.Empty empty_field = 4;
google.protobuf.FieldMask field_mask_field = 5;
google.protobuf.SourceContext source_context_field = 6;
google.protobuf.Struct struct_field = 7;
google.protobuf.Timestamp timestamp_field = 8;
google.protobuf.Type type_field = 9;
google.protobuf.DoubleValue double_field = 10;
google.protobuf.FloatValue float_field = 11;
google.protobuf.Int64Value int64_field = 12;
google.protobuf.UInt64Value uint64_field = 13;
google.protobuf.Int32Value int32_field = 14;
google.protobuf.UInt32Value uint32_field = 15;
google.protobuf.BoolValue bool_field = 16;
google.protobuf.StringValue string_field = 17;
google.protobuf.BytesValue bytes_field = 18;
// Part of struct, but useful to be able to test separately
google.protobuf.Value value_field = 19;
}
// A repeated field for each well-known type.
message RepeatedWellKnownTypes {
repeated google.protobuf.Any any_field = 1;
repeated google.protobuf.Api api_field = 2;
repeated google.protobuf.Duration duration_field = 3;
repeated google.protobuf.Empty empty_field = 4;
repeated google.protobuf.FieldMask field_mask_field = 5;
repeated google.protobuf.SourceContext source_context_field = 6;
repeated google.protobuf.Struct struct_field = 7;
repeated google.protobuf.Timestamp timestamp_field = 8;
repeated google.protobuf.Type type_field = 9;
// These don't actually make a lot of sense, but they're not prohibited...
repeated google.protobuf.DoubleValue double_field = 10;
repeated google.protobuf.FloatValue float_field = 11;
repeated google.protobuf.Int64Value int64_field = 12;
repeated google.protobuf.UInt64Value uint64_field = 13;
repeated google.protobuf.Int32Value int32_field = 14;
repeated google.protobuf.UInt32Value uint32_field = 15;
repeated google.protobuf.BoolValue bool_field = 16;
repeated google.protobuf.StringValue string_field = 17;
repeated google.protobuf.BytesValue bytes_field = 18;
}
message OneofWellKnownTypes {
oneof oneof_field {
google.protobuf.Any any_field = 1;
google.protobuf.Api api_field = 2;
google.protobuf.Duration duration_field = 3;
google.protobuf.Empty empty_field = 4;
google.protobuf.FieldMask field_mask_field = 5;
google.protobuf.SourceContext source_context_field = 6;
google.protobuf.Struct struct_field = 7;
google.protobuf.Timestamp timestamp_field = 8;
google.protobuf.Type type_field = 9;
google.protobuf.DoubleValue double_field = 10;
google.protobuf.FloatValue float_field = 11;
google.protobuf.Int64Value int64_field = 12;
google.protobuf.UInt64Value uint64_field = 13;
google.protobuf.Int32Value int32_field = 14;
google.protobuf.UInt32Value uint32_field = 15;
google.protobuf.BoolValue bool_field = 16;
google.protobuf.StringValue string_field = 17;
google.protobuf.BytesValue bytes_field = 18;
}
}
// A map field for each well-known type. We only
// need to worry about the value part of the map being the
// well-known types, as messages can't be map keys.
message MapWellKnownTypes {
map<int32,google.protobuf.Any> any_field = 1;
map<int32,google.protobuf.Api> api_field = 2;
map<int32,google.protobuf.Duration> duration_field = 3;
map<int32,google.protobuf.Empty> empty_field = 4;
map<int32,google.protobuf.FieldMask> field_mask_field = 5;
map<int32,google.protobuf.SourceContext> source_context_field = 6;
map<int32,google.protobuf.Struct> struct_field = 7;
map<int32,google.protobuf.Timestamp> timestamp_field = 8;
map<int32,google.protobuf.Type> type_field = 9;
map<int32,google.protobuf.DoubleValue> double_field = 10;
map<int32,google.protobuf.FloatValue> float_field = 11;
map<int32,google.protobuf.Int64Value> int64_field = 12;
map<int32,google.protobuf.UInt64Value> uint64_field = 13;
map<int32,google.protobuf.Int32Value> int32_field = 14;
map<int32,google.protobuf.UInt32Value> uint32_field = 15;
map<int32,google.protobuf.BoolValue> bool_field = 16;
map<int32,google.protobuf.StringValue> string_field = 17;
map<int32,google.protobuf.BytesValue> bytes_field = 18;
}

View file

@ -0,0 +1,171 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 System;
using System.Text;
using NUnit.Framework;
namespace Google.Protobuf
{
public class ByteStringTest
{
[Test]
public void Equality()
{
ByteString b1 = ByteString.CopyFrom(1, 2, 3);
ByteString b2 = ByteString.CopyFrom(1, 2, 3);
ByteString b3 = ByteString.CopyFrom(1, 2, 4);
ByteString b4 = ByteString.CopyFrom(1, 2, 3, 4);
EqualityTester.AssertEquality(b1, b1);
EqualityTester.AssertEquality(b1, b2);
EqualityTester.AssertInequality(b1, b3);
EqualityTester.AssertInequality(b1, b4);
EqualityTester.AssertInequality(b1, null);
#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
Assert.IsTrue(b1 == b1);
Assert.IsTrue(b1 == b2);
Assert.IsFalse(b1 == b3);
Assert.IsFalse(b1 == b4);
Assert.IsFalse(b1 == null);
Assert.IsTrue((ByteString) null == null);
Assert.IsFalse(b1 != b1);
Assert.IsFalse(b1 != b2);
#pragma warning disable 1718
Assert.IsTrue(b1 != b3);
Assert.IsTrue(b1 != b4);
Assert.IsTrue(b1 != null);
Assert.IsFalse((ByteString) null != null);
}
[Test]
public void EmptyByteStringHasZeroSize()
{
Assert.AreEqual(0, ByteString.Empty.Length);
}
[Test]
public void CopyFromStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
Assert.AreEqual(4, bs.Length);
Assert.AreEqual(65, bs[0]);
Assert.AreEqual(0, bs[1]);
Assert.AreEqual(66, bs[2]);
Assert.AreEqual(0, bs[3]);
}
[Test]
public void IsEmptyWhenEmpty()
{
Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
}
[Test]
public void IsEmptyWhenNotEmpty()
{
Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
}
[Test]
public void CopyFromByteArrayCopiesContents()
{
byte[] data = new byte[1];
data[0] = 10;
ByteString bs = ByteString.CopyFrom(data);
Assert.AreEqual(10, bs[0]);
data[0] = 5;
Assert.AreEqual(10, bs[0]);
}
[Test]
public void ToByteArrayCopiesContents()
{
ByteString bs = ByteString.CopyFromUtf8("Hello");
byte[] data = bs.ToByteArray();
Assert.AreEqual((byte)'H', data[0]);
Assert.AreEqual((byte)'H', bs[0]);
data[0] = 0;
Assert.AreEqual(0, data[0]);
Assert.AreEqual((byte)'H', bs[0]);
}
[Test]
public void CopyFromUtf8UsesUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(0xe2, bs[0]);
Assert.AreEqual(0x82, bs[1]);
Assert.AreEqual(0xac, bs[2]);
}
[Test]
public void CopyFromPortion()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
ByteString bs = ByteString.CopyFrom(data, 2, 3);
Assert.AreEqual(3, bs.Length);
Assert.AreEqual(2, bs[0]);
Assert.AreEqual(3, bs[1]);
}
[Test]
public void ToStringUtf8()
{
ByteString bs = ByteString.CopyFromUtf8("\u20ac");
Assert.AreEqual("\u20ac", bs.ToStringUtf8());
}
[Test]
public void ToStringWithExplicitEncoding()
{
ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
}
[Test]
public void FromBase64_WithText()
{
byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
string base64 = Convert.ToBase64String(data);
ByteString bs = ByteString.FromBase64(base64);
Assert.AreEqual(data, bs.ToByteArray());
}
[Test]
public void FromBase64_Empty()
{
// Optimization which also fixes issue 61.
Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
}
}
}

View file

@ -0,0 +1,53 @@
#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 NUnit.Framework;
namespace Google.Protobuf
{
internal static class CodedInputStreamExtensions
{
public static void AssertNextTag(this CodedInputStream input, uint expectedTag)
{
uint tag = input.ReadTag();
Assert.AreEqual(expectedTag, tag);
}
public static T ReadMessage<T>(this CodedInputStream stream, MessageParser<T> parser)
where T : IMessage<T>
{
var message = parser.CreateTemplate();
stream.ReadMessage(message);
return message;
}
}
}

View file

@ -0,0 +1,598 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 System;
using System.IO;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class CodedInputStreamTest
{
/// <summary>
/// Helper to construct a byte array from a bunch of bytes. The inputs are
/// actually ints so that I can use hex notation and not get stupid errors
/// about precision.
/// </summary>
private static byte[] Bytes(params int[] bytesAsInts)
{
byte[] bytes = new byte[bytesAsInts.Length];
for (int i = 0; i < bytesAsInts.Length; i++)
{
bytes[i] = (byte) bytesAsInts[i];
}
return bytes;
}
/// <summary>
/// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
/// </summary>
private static void AssertReadVarint(byte[] data, ulong value)
{
CodedInputStream input = new CodedInputStream(data);
Assert.AreEqual((uint) value, input.ReadRawVarint32());
input = new CodedInputStream(data);
Assert.AreEqual(value, input.ReadRawVarint64());
Assert.IsTrue(input.IsAtEnd);
// Try different block sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
Assert.AreEqual((uint) value, input.ReadRawVarint32());
input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
Assert.AreEqual(value, input.ReadRawVarint64());
Assert.IsTrue(input.IsAtEnd);
}
// Try reading directly from a MemoryStream. We want to verify that it
// doesn't read past the end of the input, so write an extra byte - this
// lets us test the position at the end.
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(data, 0, data.Length);
memoryStream.WriteByte(0);
memoryStream.Position = 0;
Assert.AreEqual((uint) value, CodedInputStream.ReadRawVarint32(memoryStream));
Assert.AreEqual(data.Length, memoryStream.Position);
}
/// <summary>
/// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
/// expects them to fail with an InvalidProtocolBufferException whose
/// description matches the given one.
/// </summary>
private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
{
CodedInputStream input = new CodedInputStream(data);
var exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint32());
Assert.AreEqual(expected.Message, exception.Message);
input = new CodedInputStream(data);
exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint64());
Assert.AreEqual(expected.Message, exception.Message);
// Make sure we get the same error when reading directly from a Stream.
exception = Assert.Throws<InvalidProtocolBufferException>(() => CodedInputStream.ReadRawVarint32(new MemoryStream(data)));
Assert.AreEqual(expected.Message, exception.Message);
}
[Test]
public void ReadVarint()
{
AssertReadVarint(Bytes(0x00), 0);
AssertReadVarint(Bytes(0x01), 1);
AssertReadVarint(Bytes(0x7f), 127);
// 14882
AssertReadVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
// 2961488830
AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x0bL << 28));
// 64-bit
// 7256456126
AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x1bL << 28));
// 41256202580718336
AssertReadVarint(Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
(0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
(0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
// 11964378330978735131
AssertReadVarint(Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
(0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3bUL << 28) | (0x56UL << 35) | (0x00UL << 42) |
(0x05UL << 49) | (0x26UL << 56) | (0x01UL << 63));
// Failures
AssertReadVarintFailure(
InvalidProtocolBufferException.MalformedVarint(),
Bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x00));
AssertReadVarintFailure(
InvalidProtocolBufferException.TruncatedMessage(),
Bytes(0x80));
}
/// <summary>
/// Parses the given bytes using ReadRawLittleEndian32() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertReadLittleEndian32(byte[] data, uint value)
{
CodedInputStream input = new CodedInputStream(data);
Assert.AreEqual(value, input.ReadRawLittleEndian32());
Assert.IsTrue(input.IsAtEnd);
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{
input = new CodedInputStream(
new SmallBlockInputStream(data, blockSize));
Assert.AreEqual(value, input.ReadRawLittleEndian32());
Assert.IsTrue(input.IsAtEnd);
}
}
/// <summary>
/// Parses the given bytes using ReadRawLittleEndian64() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertReadLittleEndian64(byte[] data, ulong value)
{
CodedInputStream input = new CodedInputStream(data);
Assert.AreEqual(value, input.ReadRawLittleEndian64());
Assert.IsTrue(input.IsAtEnd);
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{
input = new CodedInputStream(
new SmallBlockInputStream(data, blockSize));
Assert.AreEqual(value, input.ReadRawLittleEndian64());
Assert.IsTrue(input.IsAtEnd);
}
}
[Test]
public void ReadLittleEndian()
{
AssertReadLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
AssertReadLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
AssertReadLittleEndian64(Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
0x123456789abcdef0L);
AssertReadLittleEndian64(
Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678UL);
}
[Test]
public void DecodeZigZag32()
{
Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0));
Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1));
Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2));
Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3));
Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE));
Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE));
Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF));
}
[Test]
public void DecodeZigZag64()
{
Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0));
Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1));
Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2));
Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3));
Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL));
Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL));
Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL));
Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL));
Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
}
[Test]
public void ReadWholeMessage_VaryingBlockSizes()
{
TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
byte[] rawBytes = message.ToByteArray();
Assert.AreEqual(rawBytes.Length, message.CalculateSize());
TestAllTypes message2 = TestAllTypes.Parser.ParseFrom(rawBytes);
Assert.AreEqual(message, message2);
// Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
message2 = TestAllTypes.Parser.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
Assert.AreEqual(message, message2);
}
}
[Test]
public void ReadHugeBlob()
{
// Allocate and initialize a 1MB blob.
byte[] blob = new byte[1 << 20];
for (int i = 0; i < blob.Length; i++)
{
blob[i] = (byte) i;
}
// Make a message containing it.
var message = new TestAllTypes { SingleBytes = ByteString.CopyFrom(blob) };
// Serialize and parse it. Make sure to parse from an InputStream, not
// directly from a ByteString, so that CodedInputStream uses buffered
// reading.
TestAllTypes message2 = TestAllTypes.Parser.ParseFrom(message.ToByteString());
Assert.AreEqual(message, message2);
}
[Test]
public void ReadMaliciouslyLargeBlob()
{
MemoryStream ms = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(ms);
uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
output.WriteRawVarint32(tag);
output.WriteRawVarint32(0x7FFFFFFF);
output.WriteRawBytes(new byte[32]); // Pad with a few random bytes.
output.Flush();
ms.Position = 0;
CodedInputStream input = new CodedInputStream(ms);
Assert.AreEqual(tag, input.ReadTag());
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
}
internal static TestRecursiveMessage MakeRecursiveMessage(int depth)
{
if (depth == 0)
{
return new TestRecursiveMessage { I = 5 };
}
else
{
return new TestRecursiveMessage { A = MakeRecursiveMessage(depth - 1) };
}
}
internal static void AssertMessageDepth(TestRecursiveMessage message, int depth)
{
if (depth == 0)
{
Assert.IsNull(message.A);
Assert.AreEqual(5, message.I);
}
else
{
Assert.IsNotNull(message.A);
AssertMessageDepth(message.A, depth - 1);
}
}
[Test]
public void MaliciousRecursion()
{
ByteString data64 = MakeRecursiveMessage(64).ToByteString();
ByteString data65 = MakeRecursiveMessage(65).ToByteString();
AssertMessageDepth(TestRecursiveMessage.Parser.ParseFrom(data64), 64);
Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(data65));
CodedInputStream input = CodedInputStream.CreateWithLimits(new MemoryStream(data64.ToByteArray()), 1000000, 63);
Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(input));
}
[Test]
public void SizeLimit()
{
// Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
// apply to the latter case.
MemoryStream ms = new MemoryStream(SampleMessages.CreateFullTestAllTypes().ToByteArray());
CodedInputStream input = CodedInputStream.CreateWithLimits(ms, 16, 100);
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(input));
}
/// <summary>
/// Tests that if we read an string that contains invalid UTF-8, no exception
/// is thrown. Instead, the invalid bytes are replaced with the Unicode
/// "replacement character" U+FFFD.
/// </summary>
[Test]
public void ReadInvalidUtf8()
{
MemoryStream ms = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(ms);
uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
output.WriteRawVarint32(tag);
output.WriteRawVarint32(1);
output.WriteRawBytes(new byte[] {0x80});
output.Flush();
ms.Position = 0;
CodedInputStream input = new CodedInputStream(ms);
Assert.AreEqual(tag, input.ReadTag());
string text = input.ReadString();
Assert.AreEqual('\ufffd', text[0]);
}
/// <summary>
/// A stream which limits the number of bytes it reads at a time.
/// We use this to make sure that CodedInputStream doesn't screw up when
/// reading in small blocks.
/// </summary>
private sealed class SmallBlockInputStream : MemoryStream
{
private readonly int blockSize;
public SmallBlockInputStream(byte[] data, int blockSize)
: base(data)
{
this.blockSize = blockSize;
}
public override int Read(byte[] buffer, int offset, int count)
{
return base.Read(buffer, offset, Math.Min(count, blockSize));
}
}
[Test]
public void TestNegativeEnum()
{
byte[] bytes = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
CodedInputStream input = new CodedInputStream(bytes);
Assert.AreEqual((int)SampleEnum.NegativeValue, input.ReadEnum());
Assert.IsTrue(input.IsAtEnd);
}
//Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
[Test]
public void TestSlowPathAvoidance()
{
using (var ms = new MemoryStream())
{
CodedOutputStream output = new CodedOutputStream(ms);
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteBytes(ByteString.CopyFrom(new byte[100]));
output.Flush();
ms.Position = 0;
CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0);
uint tag = input.ReadTag();
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length);
tag = input.ReadTag();
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
Assert.AreEqual(100, input.ReadBytes().Length);
}
}
[Test]
public void Tag0Throws()
{
var input = new CodedInputStream(new byte[] { 0 });
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadTag());
}
[Test]
public void SkipGroup()
{
// Create an output stream with a group in:
// Field 1: string "field 1"
// Field 2: group containing:
// Field 1: fixed int32 value 100
// Field 2: string "ignore me"
// Field 3: nested group containing
// Field 1: fixed int64 value 1000
// Field 3: string "field 3"
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteString("field 1");
// The outer group...
output.WriteTag(2, WireFormat.WireType.StartGroup);
output.WriteTag(1, WireFormat.WireType.Fixed32);
output.WriteFixed32(100);
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteString("ignore me");
// The nested group...
output.WriteTag(3, WireFormat.WireType.StartGroup);
output.WriteTag(1, WireFormat.WireType.Fixed64);
output.WriteFixed64(1000);
// Note: Not sure the field number is relevant for end group...
output.WriteTag(3, WireFormat.WireType.EndGroup);
// End the outer group
output.WriteTag(2, WireFormat.WireType.EndGroup);
output.WriteTag(3, WireFormat.WireType.LengthDelimited);
output.WriteString("field 3");
output.Flush();
stream.Position = 0;
// Now act like a generated client
var input = new CodedInputStream(stream);
Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
Assert.AreEqual("field 1", input.ReadString());
Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
input.SkipLastField(); // Should consume the whole group, including the nested one.
Assert.AreEqual(WireFormat.MakeTag(3, WireFormat.WireType.LengthDelimited), input.ReadTag());
Assert.AreEqual("field 3", input.ReadString());
}
[Test]
public void SkipGroup_WrongEndGroupTag()
{
// Create an output stream with:
// Field 1: string "field 1"
// Start group 2
// Field 3: fixed int32
// End group 4 (should give an error)
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteString("field 1");
// The outer group...
output.WriteTag(2, WireFormat.WireType.StartGroup);
output.WriteTag(3, WireFormat.WireType.Fixed32);
output.WriteFixed32(100);
output.WriteTag(4, WireFormat.WireType.EndGroup);
output.Flush();
stream.Position = 0;
// Now act like a generated client
var input = new CodedInputStream(stream);
Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
Assert.AreEqual("field 1", input.ReadString());
Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
public void RogueEndGroupTag()
{
// If we have an end-group tag without a leading start-group tag, generated
// code will just call SkipLastField... so that should fail.
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(1, WireFormat.WireType.EndGroup);
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
public void EndOfStreamReachedWhileSkippingGroup()
{
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(1, WireFormat.WireType.StartGroup);
output.WriteTag(2, WireFormat.WireType.StartGroup);
output.WriteTag(2, WireFormat.WireType.EndGroup);
output.Flush();
stream.Position = 0;
// Now act like a generated client
var input = new CodedInputStream(stream);
input.ReadTag();
Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
public void RecursionLimitAppliedWhileSkippingGroup()
{
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
{
output.WriteTag(1, WireFormat.WireType.StartGroup);
}
for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
{
output.WriteTag(1, WireFormat.WireType.EndGroup);
}
output.Flush();
stream.Position = 0;
// Now act like a generated client
var input = new CodedInputStream(stream);
Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
public void Construction_Invalid()
{
Assert.Throws<ArgumentNullException>(() => new CodedInputStream((byte[]) null));
Assert.Throws<ArgumentNullException>(() => new CodedInputStream(null, 0, 0));
Assert.Throws<ArgumentNullException>(() => new CodedInputStream((Stream) null));
Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 100, 0));
Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 5, 10));
}
[Test]
public void CreateWithLimits_InvalidLimits()
{
var stream = new MemoryStream();
Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
}
[Test]
public void Dispose_DisposesUnderlyingStream()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanRead);
using (var cis = new CodedInputStream(memoryStream))
{
}
Assert.IsFalse(memoryStream.CanRead); // Disposed
}
[Test]
public void Dispose_WithLeaveOpen()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanRead);
using (var cis = new CodedInputStream(memoryStream, true))
{
}
Assert.IsTrue(memoryStream.CanRead); // We left the stream open
}
}
}

View file

@ -0,0 +1,419 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 System;
using System.IO;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class CodedOutputStreamTest
{
/// <summary>
/// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
/// checks that the result matches the given bytes
/// </summary>
private static void AssertWriteVarint(byte[] data, ulong value)
{
// Only do 32-bit write if the value fits in 32 bits.
if ((value >> 32) == 0)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
}
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Also try computing size.
Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
}
// Try different buffer sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
// Only do 32-bit write if the value fits in 32 bits.
if ((value >> 32) == 0)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output =
new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint32((uint) value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawVarint64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
}
/// <summary>
/// Tests WriteRawVarint32() and WriteRawVarint64()
/// </summary>
[Test]
public void WriteVarint()
{
AssertWriteVarint(new byte[] {0x00}, 0);
AssertWriteVarint(new byte[] {0x01}, 1);
AssertWriteVarint(new byte[] {0x7f}, 127);
// 14882
AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
// 2961488830
AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x0bL << 28));
// 64-bit
// 7256456126
AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x1bL << 28));
// 41256202580718336
AssertWriteVarint(
new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
(0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
(0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
// 11964378330978735131
AssertWriteVarint(
new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
unchecked((ulong)
((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
(0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian32() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertWriteLittleEndian32(byte[] data, uint value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Try different buffer sizes.
for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, bufferSize);
output.WriteRawLittleEndian32(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
/// <summary>
/// Parses the given bytes using WriteRawLittleEndian64() and checks
/// that the result matches the given value.
/// </summary>
private static void AssertWriteLittleEndian64(byte[] data, ulong value)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
{
rawOutput = new MemoryStream();
output = new CodedOutputStream(rawOutput, blockSize);
output.WriteRawLittleEndian64(value);
output.Flush();
Assert.AreEqual(data, rawOutput.ToArray());
}
}
/// <summary>
/// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
/// </summary>
[Test]
public void WriteLittleEndian()
{
AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
AssertWriteLittleEndian64(
new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
0x123456789abcdef0L);
AssertWriteLittleEndian64(
new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
0x9abcdef012345678UL);
}
[Test]
public void WriteWholeMessage_VaryingBlockSizes()
{
TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
byte[] rawBytes = message.ToByteArray();
// Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
MemoryStream rawOutput = new MemoryStream();
CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
message.WriteTo(output);
output.Flush();
Assert.AreEqual(rawBytes, rawOutput.ToArray());
}
}
[Test]
public void EncodeZigZag32()
{
Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
}
[Test]
public void EncodeZigZag64()
{
Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
Assert.AreEqual(0x000000007FFFFFFEuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
Assert.AreEqual(0x000000007FFFFFFFuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
Assert.AreEqual(0x00000000FFFFFFFEuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
Assert.AreEqual(0x00000000FFFFFFFFuL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
}
[Test]
public void RoundTripZigZag32()
{
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
}
[Test]
public void RoundTripZigZag64()
{
Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
Assert.AreEqual(856912304801416L,
CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
Assert.AreEqual(-75123905439571256L,
CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
}
[Test]
public void TestNegativeEnumNoTag()
{
Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
byte[] bytes = new byte[10];
CodedOutputStream output = new CodedOutputStream(bytes);
output.WriteEnum((int) SampleEnum.NegativeValue);
Assert.AreEqual(0, output.SpaceLeft);
Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
}
[Test]
public void TestCodedInputOutputPosition()
{
byte[] content = new byte[110];
for (int i = 0; i < content.Length; i++)
content[i] = (byte)i;
byte[] child = new byte[120];
{
MemoryStream ms = new MemoryStream(child);
CodedOutputStream cout = new CodedOutputStream(ms, 20);
// Field 11: numeric value: 500
cout.WriteTag(11, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position);
cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position);
//Field 12: length delimited 120 bytes
cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position);
cout.WriteBytes(ByteString.CopyFrom(content));
Assert.AreEqual(115, cout.Position);
// Field 13: fixed numeric value: 501
cout.WriteTag(13, WireFormat.WireType.Fixed32);
Assert.AreEqual(116, cout.Position);
cout.WriteSFixed32(501);
Assert.AreEqual(120, cout.Position);
cout.Flush();
}
byte[] bytes = new byte[130];
{
CodedOutputStream cout = new CodedOutputStream(bytes);
// Field 1: numeric value: 500
cout.WriteTag(1, WireFormat.WireType.Varint);
Assert.AreEqual(1, cout.Position);
cout.WriteInt32(500);
Assert.AreEqual(3, cout.Position);
//Field 2: length delimited 120 bytes
cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
Assert.AreEqual(4, cout.Position);
cout.WriteBytes(ByteString.CopyFrom(child));
Assert.AreEqual(125, cout.Position);
// Field 3: fixed numeric value: 500
cout.WriteTag(3, WireFormat.WireType.Fixed32);
Assert.AreEqual(126, cout.Position);
cout.WriteSFixed32(501);
Assert.AreEqual(130, cout.Position);
cout.Flush();
}
// Now test Input stream:
{
CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0);
Assert.AreEqual(0, cin.Position);
// Field 1:
uint tag = cin.ReadTag();
Assert.AreEqual(1, tag >> 3);
Assert.AreEqual(1, cin.Position);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(3, cin.Position);
//Field 2:
tag = cin.ReadTag();
Assert.AreEqual(2, tag >> 3);
Assert.AreEqual(4, cin.Position);
int childlen = cin.ReadLength();
Assert.AreEqual(120, childlen);
Assert.AreEqual(5, cin.Position);
int oldlimit = cin.PushLimit((int)childlen);
Assert.AreEqual(5, cin.Position);
// Now we are reading child message
{
// Field 11: numeric value: 500
tag = cin.ReadTag();
Assert.AreEqual(11, tag >> 3);
Assert.AreEqual(6, cin.Position);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(8, cin.Position);
//Field 12: length delimited 120 bytes
tag = cin.ReadTag();
Assert.AreEqual(12, tag >> 3);
Assert.AreEqual(9, cin.Position);
ByteString bstr = cin.ReadBytes();
Assert.AreEqual(110, bstr.Length);
Assert.AreEqual((byte) 109, bstr[109]);
Assert.AreEqual(120, cin.Position);
// Field 13: fixed numeric value: 501
tag = cin.ReadTag();
Assert.AreEqual(13, tag >> 3);
// ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
Assert.AreEqual(121, cin.Position);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(125, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
cin.PopLimit(oldlimit);
Assert.AreEqual(125, cin.Position);
// Field 3: fixed numeric value: 501
tag = cin.ReadTag();
Assert.AreEqual(3, tag >> 3);
Assert.AreEqual(126, cin.Position);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(130, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
}
[Test]
public void Dispose_DisposesUnderlyingStream()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream))
{
cos.WriteRawByte(0);
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
Assert.IsFalse(memoryStream.CanWrite); // Disposed
}
[Test]
public void Dispose_WithLeaveOpen()
{
var memoryStream = new MemoryStream();
Assert.IsTrue(memoryStream.CanWrite);
using (var cos = new CodedOutputStream(memoryStream, true))
{
cos.WriteRawByte(0);
Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
}
Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
}
}
}

View file

@ -0,0 +1,532 @@
#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 System;
using System.Collections.Generic;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Collections;
using System.Linq;
namespace Google.Protobuf.Collections
{
/// <summary>
/// Tests for MapField which aren't reliant on the encoded format -
/// tests for serialization/deserialization are part of GeneratedMessageTest.
/// </summary>
public class MapFieldTest
{
[Test]
public void Clone_ClonesMessages()
{
var message = new ForeignMessage { C = 20 };
var map = new MapField<string, ForeignMessage> { { "x", message } };
var clone = map.Clone();
map["x"].C = 30;
Assert.AreEqual(20, clone["x"].C);
}
[Test]
public void NullValuesProhibited()
{
TestNullValues<int?>(0);
TestNullValues("");
TestNullValues(new TestAllTypes());
}
private void TestNullValues<T>(T nonNullValue)
{
var map = new MapField<int, T>();
var nullValue = (T) (object) null;
Assert.Throws<ArgumentNullException>(() => map.Add(0, nullValue));
Assert.Throws<ArgumentNullException>(() => map[0] = nullValue);
map.Add(1, nonNullValue);
map[1] = nonNullValue;
}
[Test]
public void Add_ForbidsNullKeys()
{
var map = new MapField<string, ForeignMessage>();
Assert.Throws<ArgumentNullException>(() => map.Add(null, new ForeignMessage()));
}
[Test]
public void Indexer_ForbidsNullKeys()
{
var map = new MapField<string, ForeignMessage>();
Assert.Throws<ArgumentNullException>(() => map[null] = new ForeignMessage());
}
[Test]
public void AddPreservesInsertionOrder()
{
var map = new MapField<string, string>();
map.Add("a", "v1");
map.Add("b", "v2");
map.Add("c", "v3");
map.Remove("b");
map.Add("d", "v4");
CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys);
CollectionAssert.AreEqual(new[] { "v1", "v3", "v4" }, map.Values);
}
[Test]
public void EqualityIsOrderInsensitive()
{
var map1 = new MapField<string, string>();
map1.Add("a", "v1");
map1.Add("b", "v2");
var map2 = new MapField<string, string>();
map2.Add("b", "v2");
map2.Add("a", "v1");
EqualityTester.AssertEquality(map1, map2);
}
[Test]
public void EqualityIsKeySensitive()
{
var map1 = new MapField<string, string>();
map1.Add("first key", "v1");
map1.Add("second key", "v2");
var map2 = new MapField<string, string>();
map2.Add("third key", "v1");
map2.Add("fourth key", "v2");
EqualityTester.AssertInequality(map1, map2);
}
[Test]
public void Equality_Simple()
{
var map = new MapField<string, string>();
EqualityTester.AssertEquality(map, map);
EqualityTester.AssertInequality(map, null);
Assert.IsFalse(map.Equals(new object()));
}
[Test]
public void EqualityIsValueSensitive()
{
// Note: Without some care, it's a little easier than one might
// hope to see hash collisions, but only in some environments...
var map1 = new MapField<string, string>();
map1.Add("a", "first value");
map1.Add("b", "second value");
var map2 = new MapField<string, string>();
map2.Add("a", "third value");
map2.Add("b", "fourth value");
EqualityTester.AssertInequality(map1, map2);
}
[Test]
public void Add_Dictionary()
{
var map1 = new MapField<string, string>
{
{ "x", "y" },
{ "a", "b" }
};
var map2 = new MapField<string, string>
{
{ "before", "" },
map1,
{ "after", "" }
};
var expected = new MapField<string, string>
{
{ "before", "" },
{ "x", "y" },
{ "a", "b" },
{ "after", "" }
};
Assert.AreEqual(expected, map2);
CollectionAssert.AreEqual(new[] { "before", "x", "a", "after" }, map2.Keys);
}
// General IDictionary<TKey, TValue> behavior tests
[Test]
public void Add_KeyAlreadyExists()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
Assert.Throws<ArgumentException>(() => map.Add("foo", "baz"));
}
[Test]
public void Add_Pair()
{
var map = new MapField<string, string>();
ICollection<KeyValuePair<string, string>> collection = map;
collection.Add(NewKeyValuePair("x", "y"));
Assert.AreEqual("y", map["x"]);
Assert.Throws<ArgumentException>(() => collection.Add(NewKeyValuePair("x", "z")));
}
[Test]
public void Contains_Pair()
{
var map = new MapField<string, string> { { "x", "y" } };
ICollection<KeyValuePair<string, string>> collection = map;
Assert.IsTrue(collection.Contains(NewKeyValuePair("x", "y")));
Assert.IsFalse(collection.Contains(NewKeyValuePair("x", "z")));
Assert.IsFalse(collection.Contains(NewKeyValuePair("z", "y")));
}
[Test]
public void Remove_Key()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
Assert.AreEqual(1, map.Count);
Assert.IsFalse(map.Remove("missing"));
Assert.AreEqual(1, map.Count);
Assert.IsTrue(map.Remove("foo"));
Assert.AreEqual(0, map.Count);
Assert.Throws<ArgumentNullException>(() => map.Remove(null));
}
[Test]
public void Remove_Pair()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
ICollection<KeyValuePair<string, string>> collection = map;
Assert.AreEqual(1, map.Count);
Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar")));
Assert.AreEqual(1, map.Count);
Assert.IsFalse(collection.Remove(NewKeyValuePair("foo", "wrong value")));
Assert.AreEqual(1, map.Count);
Assert.IsTrue(collection.Remove(NewKeyValuePair("foo", "bar")));
Assert.AreEqual(0, map.Count);
Assert.Throws<ArgumentException>(() => collection.Remove(new KeyValuePair<string, string>(null, "")));
}
[Test]
public void CopyTo_Pair()
{
var map = new MapField<string, string>();
map.Add("foo", "bar");
ICollection<KeyValuePair<string, string>> collection = map;
KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3];
collection.CopyTo(array, 1);
Assert.AreEqual(NewKeyValuePair("foo", "bar"), array[1]);
}
[Test]
public void Clear()
{
var map = new MapField<string, string> { { "x", "y" } };
Assert.AreEqual(1, map.Count);
map.Clear();
Assert.AreEqual(0, map.Count);
map.Add("x", "y");
Assert.AreEqual(1, map.Count);
}
[Test]
public void Indexer_Get()
{
var map = new MapField<string, string> { { "x", "y" } };
Assert.AreEqual("y", map["x"]);
Assert.Throws<KeyNotFoundException>(() => { var ignored = map["z"]; });
}
[Test]
public void Indexer_Set()
{
var map = new MapField<string, string>();
map["x"] = "y";
Assert.AreEqual("y", map["x"]);
map["x"] = "z"; // This won't throw, unlike Add.
Assert.AreEqual("z", map["x"]);
}
[Test]
public void GetEnumerator_NonGeneric()
{
IEnumerable map = new MapField<string, string> { { "x", "y" } };
CollectionAssert.AreEqual(new[] { new KeyValuePair<string, string>("x", "y") },
map.Cast<object>().ToList());
}
// Test for the explicitly-implemented non-generic IDictionary interface
[Test]
public void IDictionary_GetEnumerator()
{
IDictionary map = new MapField<string, string> { { "x", "y" } };
var enumerator = map.GetEnumerator();
// Commented assertions show an ideal situation - it looks like
// the LinkedList enumerator doesn't throw when you ask for the current entry
// at an inappropriate time; fixing this would be more work than it's worth.
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("x", enumerator.Key);
Assert.AreEqual("y", enumerator.Value);
Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Current);
Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Entry);
Assert.IsFalse(enumerator.MoveNext());
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
enumerator.Reset();
// Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("x", enumerator.Key); // Assume the rest are okay
}
[Test]
public void IDictionary_Add()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
dictionary.Add("a", "b");
Assert.AreEqual("b", map["a"]);
Assert.Throws<ArgumentException>(() => dictionary.Add("a", "duplicate"));
Assert.Throws<InvalidCastException>(() => dictionary.Add(new object(), "key is bad"));
Assert.Throws<InvalidCastException>(() => dictionary.Add("value is bad", new object()));
}
[Test]
public void IDictionary_Contains()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
Assert.IsFalse(dictionary.Contains("a"));
Assert.IsFalse(dictionary.Contains(5));
// Surprising, but IDictionary.Contains is only about keys.
Assert.IsFalse(dictionary.Contains(new DictionaryEntry("x", "y")));
Assert.IsTrue(dictionary.Contains("x"));
}
[Test]
public void IDictionary_Remove()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
dictionary.Remove("a");
Assert.AreEqual(1, dictionary.Count);
dictionary.Remove(5);
Assert.AreEqual(1, dictionary.Count);
dictionary.Remove(new DictionaryEntry("x", "y"));
Assert.AreEqual(1, dictionary.Count);
dictionary.Remove("x");
Assert.AreEqual(0, dictionary.Count);
Assert.Throws<ArgumentNullException>(() => dictionary.Remove(null));
}
[Test]
public void IDictionary_CopyTo()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
var array = new DictionaryEntry[3];
dictionary.CopyTo(array, 1);
CollectionAssert.AreEqual(new[] { default(DictionaryEntry), new DictionaryEntry("x", "y"), default(DictionaryEntry) },
array);
var objectArray = new object[3];
dictionary.CopyTo(objectArray, 1);
CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null },
objectArray);
}
[Test]
public void IDictionary_IsFixedSize()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
Assert.IsFalse(dictionary.IsFixedSize);
}
[Test]
public void IDictionary_Keys()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
CollectionAssert.AreEqual(new[] { "x" }, dictionary.Keys);
}
[Test]
public void IDictionary_Values()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
CollectionAssert.AreEqual(new[] { "y" }, dictionary.Values);
}
[Test]
public void IDictionary_IsSynchronized()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
Assert.IsFalse(dictionary.IsSynchronized);
}
[Test]
public void IDictionary_SyncRoot()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
Assert.AreSame(dictionary, dictionary.SyncRoot);
}
[Test]
public void IDictionary_Indexer_Get()
{
IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
Assert.AreEqual("y", dictionary["x"]);
Assert.IsNull(dictionary["a"]);
Assert.IsNull(dictionary[5]);
Assert.Throws<ArgumentNullException>(() => dictionary[null].GetHashCode());
}
[Test]
public void IDictionary_Indexer_Set()
{
var map = new MapField<string, string> { { "x", "y" } };
IDictionary dictionary = map;
map["a"] = "b";
Assert.AreEqual("b", map["a"]);
map["a"] = "c";
Assert.AreEqual("c", map["a"]);
Assert.Throws<InvalidCastException>(() => dictionary[5] = "x");
Assert.Throws<InvalidCastException>(() => dictionary["x"] = 5);
Assert.Throws<ArgumentNullException>(() => dictionary[null] = "z");
Assert.Throws<ArgumentNullException>(() => dictionary["x"] = null);
}
[Test]
public void KeysReturnsLiveView()
{
var map = new MapField<string, string>();
var keys = map.Keys;
CollectionAssert.AreEqual(new string[0], keys);
map["foo"] = "bar";
map["x"] = "y";
CollectionAssert.AreEqual(new[] { "foo", "x" }, keys);
}
[Test]
public void ValuesReturnsLiveView()
{
var map = new MapField<string, string>();
var values = map.Values;
CollectionAssert.AreEqual(new string[0], values);
map["foo"] = "bar";
map["x"] = "y";
CollectionAssert.AreEqual(new[] { "bar", "y" }, values);
}
// Just test keys - we know the implementation is the same for values
[Test]
public void ViewsAreReadOnly()
{
var map = new MapField<string, string>();
var keys = map.Keys;
Assert.IsTrue(keys.IsReadOnly);
Assert.Throws<NotSupportedException>(() => keys.Clear());
Assert.Throws<NotSupportedException>(() => keys.Remove("a"));
Assert.Throws<NotSupportedException>(() => keys.Add("a"));
}
// Just test keys - we know the implementation is the same for values
[Test]
public void ViewCopyTo()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var keys = map.Keys;
var array = new string[4];
Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
keys.CopyTo(array, 1);
CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
}
// Just test keys - we know the implementation is the same for values
[Test]
public void NonGenericViewCopyTo()
{
IDictionary map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
ICollection keys = map.Keys;
// Note the use of the Array type here rather than string[]
Array array = new string[4];
Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
keys.CopyTo(array, 1);
CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
}
[Test]
public void KeysContains()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var keys = map.Keys;
Assert.IsTrue(keys.Contains("foo"));
Assert.IsFalse(keys.Contains("bar")); // It's a value!
Assert.IsFalse(keys.Contains("1"));
// Keys can't be null, so we should prevent contains check
Assert.Throws<ArgumentNullException>(() => keys.Contains(null));
}
[Test]
public void ValuesContains()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var values = map.Values;
Assert.IsTrue(values.Contains("bar"));
Assert.IsFalse(values.Contains("foo")); // It's a key!
Assert.IsFalse(values.Contains("1"));
// Values can be null, so this makes sense
Assert.IsFalse(values.Contains(null));
}
[Test]
public void ToString_StringToString()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
Assert.AreEqual("{ \"foo\": \"bar\", \"x\": \"y\" }", map.ToString());
}
[Test]
public void ToString_UnsupportedKeyType()
{
var map = new MapField<byte, string> { { 10, "foo" } };
Assert.Throws<ArgumentException>(() => map.ToString());
}
private static KeyValuePair<TKey, TValue> NewKeyValuePair<TKey, TValue>(TKey key, TValue value)
{
return new KeyValuePair<TKey, TValue>(key, value);
}
}
}

View file

@ -0,0 +1,746 @@
#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 System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Google.Protobuf.TestProtos;
using Google.Protobuf.WellKnownTypes;
using NUnit.Framework;
namespace Google.Protobuf.Collections
{
public class RepeatedFieldTest
{
[Test]
public void NullValuesRejected()
{
var list = new RepeatedField<string>();
Assert.Throws<ArgumentNullException>(() => list.Add((string)null));
Assert.Throws<ArgumentNullException>(() => list.Add((IEnumerable<string>)null));
Assert.Throws<ArgumentNullException>(() => list.Add((RepeatedField<string>)null));
Assert.Throws<ArgumentNullException>(() => list.Contains(null));
Assert.Throws<ArgumentNullException>(() => list.IndexOf(null));
}
[Test]
public void Add_SingleItem()
{
var list = new RepeatedField<string>();
list.Add("foo");
Assert.AreEqual(1, list.Count);
Assert.AreEqual("foo", list[0]);
}
[Test]
public void Add_Sequence()
{
var list = new RepeatedField<string>();
list.Add(new[] { "foo", "bar" });
Assert.AreEqual(2, list.Count);
Assert.AreEqual("foo", list[0]);
Assert.AreEqual("bar", list[1]);
}
[Test]
public void AddRange_SlowPath()
{
var list = new RepeatedField<string>();
list.AddRange(new[] { "foo", "bar" }.Select(x => x));
Assert.AreEqual(2, list.Count);
Assert.AreEqual("foo", list[0]);
Assert.AreEqual("bar", list[1]);
}
[Test]
public void AddRange_SlowPath_NullsProhibited_ReferenceType()
{
var list = new RepeatedField<string>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert.Catch<ArgumentException>(() => list.AddRange(new[] { "foo", null }.Select(x => x)));
}
[Test]
public void AddRange_SlowPath_NullsProhibited_NullableValueType()
{
var list = new RepeatedField<int?>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert.Catch<ArgumentException>(() => list.AddRange(new[] { 20, (int?)null }.Select(x => x)));
}
[Test]
public void AddRange_Optimized_NonNullableValueType()
{
var list = new RepeatedField<int>();
list.AddRange(new List<int> { 20, 30 });
Assert.AreEqual(2, list.Count);
Assert.AreEqual(20, list[0]);
Assert.AreEqual(30, list[1]);
}
[Test]
public void AddRange_Optimized_ReferenceType()
{
var list = new RepeatedField<string>();
list.AddRange(new List<string> { "foo", "bar" });
Assert.AreEqual(2, list.Count);
Assert.AreEqual("foo", list[0]);
Assert.AreEqual("bar", list[1]);
}
[Test]
public void AddRange_Optimized_NullableValueType()
{
var list = new RepeatedField<int?>();
list.AddRange(new List<int?> { 20, 30 });
Assert.AreEqual(2, list.Count);
Assert.AreEqual((int?) 20, list[0]);
Assert.AreEqual((int?) 30, list[1]);
}
[Test]
public void AddRange_Optimized_NullsProhibited_ReferenceType()
{
// We don't just trust that a collection with a nullable element type doesn't contain nulls
var list = new RepeatedField<string>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert.Catch<ArgumentException>(() => list.AddRange(new List<string> { "foo", null }));
}
[Test]
public void AddRange_Optimized_NullsProhibited_NullableValueType()
{
// We don't just trust that a collection with a nullable element type doesn't contain nulls
var list = new RepeatedField<int?>();
// It's okay for this to throw ArgumentNullException if necessary.
// It's not ideal, but not awful.
Assert.Catch<ArgumentException>(() => list.AddRange(new List<int?> { 20, null }));
}
[Test]
public void AddRange_AlreadyNotEmpty()
{
var list = new RepeatedField<int> { 1, 2, 3 };
list.AddRange(new List<int> { 4, 5, 6 });
CollectionAssert.AreEqual(new[] { 1, 2, 3, 4, 5, 6 }, list);
}
[Test]
public void AddRange_RepeatedField()
{
var list = new RepeatedField<string> { "original" };
list.AddRange(new RepeatedField<string> { "foo", "bar" });
Assert.AreEqual(3, list.Count);
Assert.AreEqual("original", list[0]);
Assert.AreEqual("foo", list[1]);
Assert.AreEqual("bar", list[2]);
}
[Test]
public void RemoveAt_Valid()
{
var list = new RepeatedField<string> { "first", "second", "third" };
list.RemoveAt(1);
CollectionAssert.AreEqual(new[] { "first", "third" }, list);
// Just check that these don't throw...
list.RemoveAt(list.Count - 1); // Now the count will be 1...
list.RemoveAt(0);
Assert.AreEqual(0, list.Count);
}
[Test]
public void RemoveAt_Invalid()
{
var list = new RepeatedField<string> { "first", "second", "third" };
Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(-1));
Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(3));
}
[Test]
public void Insert_Valid()
{
var list = new RepeatedField<string> { "first", "second" };
list.Insert(1, "middle");
CollectionAssert.AreEqual(new[] { "first", "middle", "second" }, list);
list.Insert(3, "end");
CollectionAssert.AreEqual(new[] { "first", "middle", "second", "end" }, list);
list.Insert(0, "start");
CollectionAssert.AreEqual(new[] { "start", "first", "middle", "second", "end" }, list);
}
[Test]
public void Insert_Invalid()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, "foo"));
Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(3, "foo"));
Assert.Throws<ArgumentNullException>(() => list.Insert(0, null));
}
[Test]
public void Equals_RepeatedField()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.IsFalse(list.Equals((RepeatedField<string>) null));
Assert.IsTrue(list.Equals(list));
Assert.IsFalse(list.Equals(new RepeatedField<string> { "first", "third" }));
Assert.IsFalse(list.Equals(new RepeatedField<string> { "first" }));
Assert.IsTrue(list.Equals(new RepeatedField<string> { "first", "second" }));
}
[Test]
public void Equals_Object()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.IsFalse(list.Equals((object) null));
Assert.IsTrue(list.Equals((object) list));
Assert.IsFalse(list.Equals((object) new RepeatedField<string> { "first", "third" }));
Assert.IsFalse(list.Equals((object) new RepeatedField<string> { "first" }));
Assert.IsTrue(list.Equals((object) new RepeatedField<string> { "first", "second" }));
Assert.IsFalse(list.Equals(new object()));
}
[Test]
public void GetEnumerator_GenericInterface()
{
IEnumerable<string> list = new RepeatedField<string> { "first", "second" };
// Select gets rid of the optimizations in ToList...
CollectionAssert.AreEqual(new[] { "first", "second" }, list.Select(x => x).ToList());
}
[Test]
public void GetEnumerator_NonGenericInterface()
{
IEnumerable list = new RepeatedField<string> { "first", "second" };
CollectionAssert.AreEqual(new[] { "first", "second" }, list.Cast<object>().ToList());
}
[Test]
public void CopyTo()
{
var list = new RepeatedField<string> { "first", "second" };
string[] stringArray = new string[4];
list.CopyTo(stringArray, 1);
CollectionAssert.AreEqual(new[] { null, "first", "second", null }, stringArray);
}
[Test]
public void Indexer_Get()
{
var list = new RepeatedField<string> { "first", "second" };
Assert.AreEqual("first", list[0]);
Assert.AreEqual("second", list[1]);
Assert.Throws<ArgumentOutOfRangeException>(() => list[-1].GetHashCode());
Assert.Throws<ArgumentOutOfRangeException>(() => list[2].GetHashCode());
}
[Test]
public void Indexer_Set()
{
var list = new RepeatedField<string> { "first", "second" };
list[0] = "changed";
Assert.AreEqual("changed", list[0]);
Assert.Throws<ArgumentNullException>(() => list[0] = null);
Assert.Throws<ArgumentOutOfRangeException>(() => list[-1] = "bad");
Assert.Throws<ArgumentOutOfRangeException>(() => list[2] = "bad");
}
[Test]
public void Clone_ReturnsMutable()
{
var list = new RepeatedField<int> { 0 };
var clone = list.Clone();
clone[0] = 1;
}
[Test]
public void Enumerator()
{
var list = new RepeatedField<string> { "first", "second" };
using (var enumerator = list.GetEnumerator())
{
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("first", enumerator.Current);
Assert.IsTrue(enumerator.MoveNext());
Assert.AreEqual("second", enumerator.Current);
Assert.IsFalse(enumerator.MoveNext());
Assert.IsFalse(enumerator.MoveNext());
}
}
[Test]
public void AddEntriesFrom_PackedInt32()
{
uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
var length = CodedOutputStream.ComputeInt32Size(10)
+ CodedOutputStream.ComputeInt32Size(999)
+ CodedOutputStream.ComputeInt32Size(-1000);
output.WriteTag(packedTag);
output.WriteRawVarint32((uint) length);
output.WriteInt32(10);
output.WriteInt32(999);
output.WriteInt32(-1000);
output.Flush();
stream.Position = 0;
// Deliberately "expecting" a non-packed tag, but we detect that the data is
// actually packed.
uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<int>();
var input = new CodedInputStream(stream);
input.AssertNextTag(packedTag);
field.AddEntriesFrom(input, FieldCodec.ForInt32(nonPackedTag));
CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void AddEntriesFrom_NonPackedInt32()
{
uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.Varint);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(nonPackedTag);
output.WriteInt32(10);
output.WriteTag(nonPackedTag);
output.WriteInt32(999);
output.WriteTag(nonPackedTag);
output.WriteInt32(-1000); // Just for variety...
output.Flush();
stream.Position = 0;
// Deliberately "expecting" a packed tag, but we detect that the data is
// actually not packed.
uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<int>();
var input = new CodedInputStream(stream);
input.AssertNextTag(nonPackedTag);
field.AddEntriesFrom(input, FieldCodec.ForInt32(packedTag));
CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void AddEntriesFrom_String()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(tag);
output.WriteString("Foo");
output.WriteTag(tag);
output.WriteString("");
output.WriteTag(tag);
output.WriteString("Bar");
output.Flush();
stream.Position = 0;
var field = new RepeatedField<string>();
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
field.AddEntriesFrom(input, FieldCodec.ForString(tag));
CollectionAssert.AreEqual(new[] { "Foo", "", "Bar" }, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void AddEntriesFrom_Message()
{
var message1 = new ForeignMessage { C = 2000 };
var message2 = new ForeignMessage { C = -250 };
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(tag);
output.WriteMessage(message1);
output.WriteTag(tag);
output.WriteMessage(message2);
output.Flush();
stream.Position = 0;
var field = new RepeatedField<ForeignMessage>();
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
field.AddEntriesFrom(input, FieldCodec.ForMessage(tag, ForeignMessage.Parser));
CollectionAssert.AreEqual(new[] { message1, message2}, field);
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void WriteTo_PackedInt32()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<int> { 10, 1000, 1000000 };
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForInt32(tag));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
var length = input.ReadLength();
Assert.AreEqual(10, input.ReadInt32());
Assert.AreEqual(1000, input.ReadInt32());
Assert.AreEqual(1000000, input.ReadInt32());
Assert.IsTrue(input.IsAtEnd);
Assert.AreEqual(1 + CodedOutputStream.ComputeLengthSize(length) + length, stream.Length);
}
[Test]
public void WriteTo_NonPackedInt32()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.Varint);
var field = new RepeatedField<int> { 10, 1000, 1000000};
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForInt32(tag));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
Assert.AreEqual(10, input.ReadInt32());
input.AssertNextTag(tag);
Assert.AreEqual(1000, input.ReadInt32());
input.AssertNextTag(tag);
Assert.AreEqual(1000000, input.ReadInt32());
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void WriteTo_String()
{
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<string> { "Foo", "", "Bar" };
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForString(tag));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
Assert.AreEqual("Foo", input.ReadString());
input.AssertNextTag(tag);
Assert.AreEqual("", input.ReadString());
input.AssertNextTag(tag);
Assert.AreEqual("Bar", input.ReadString());
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void WriteTo_Message()
{
var message1 = new ForeignMessage { C = 20 };
var message2 = new ForeignMessage { C = 25 };
uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
var field = new RepeatedField<ForeignMessage> { message1, message2 };
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
field.WriteTo(output, FieldCodec.ForMessage(tag, ForeignMessage.Parser));
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.AssertNextTag(tag);
Assert.AreEqual(message1, input.ReadMessage(ForeignMessage.Parser));
input.AssertNextTag(tag);
Assert.AreEqual(message2, input.ReadMessage(ForeignMessage.Parser));
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void CalculateSize_VariableSizeNonPacked()
{
var list = new RepeatedField<int> { 1, 500, 1 };
var tag = WireFormat.MakeTag(1, WireFormat.WireType.Varint);
// 2 bytes for the first entry, 3 bytes for the second, 2 bytes for the third
Assert.AreEqual(7, list.CalculateSize(FieldCodec.ForInt32(tag)));
}
[Test]
public void CalculateSize_FixedSizeNonPacked()
{
var list = new RepeatedField<int> { 1, 500, 1 };
var tag = WireFormat.MakeTag(1, WireFormat.WireType.Fixed32);
// 5 bytes for the each entry
Assert.AreEqual(15, list.CalculateSize(FieldCodec.ForSFixed32(tag)));
}
[Test]
public void CalculateSize_VariableSizePacked()
{
var list = new RepeatedField<int> { 1, 500, 1};
var tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
// 1 byte for the tag, 1 byte for the length,
// 1 byte for the first entry, 2 bytes for the second, 1 byte for the third
Assert.AreEqual(6, list.CalculateSize(FieldCodec.ForInt32(tag)));
}
[Test]
public void CalculateSize_FixedSizePacked()
{
var list = new RepeatedField<int> { 1, 500, 1 };
var tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
// 1 byte for the tag, 1 byte for the length, 4 bytes per entry
Assert.AreEqual(14, list.CalculateSize(FieldCodec.ForSFixed32(tag)));
}
[Test]
public void TestNegativeEnumArray()
{
int arraySize = 1 + 1 + (11 * 5);
int msgSize = arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = new CodedOutputStream(bytes);
uint tag = WireFormat.MakeTag(8, WireFormat.WireType.Varint);
for (int i = 0; i >= -5; i--)
{
output.WriteTag(tag);
output.WriteEnum(i);
}
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = new CodedInputStream(bytes);
tag = input.ReadTag();
RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>();
values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x));
Assert.AreEqual(6, values.Count);
Assert.AreEqual(SampleEnum.None, values[0]);
Assert.AreEqual(((SampleEnum)(-1)), values[1]);
Assert.AreEqual(SampleEnum.NegativeValue, values[2]);
Assert.AreEqual(((SampleEnum)(-3)), values[3]);
Assert.AreEqual(((SampleEnum)(-4)), values[4]);
Assert.AreEqual(((SampleEnum)(-5)), values[5]);
}
[Test]
public void TestNegativeEnumPackedArray()
{
int arraySize = 1 + (10 * 5);
int msgSize = 1 + 1 + arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = new CodedOutputStream(bytes);
// Length-delimited to show we want the packed representation
uint tag = WireFormat.MakeTag(8, WireFormat.WireType.LengthDelimited);
output.WriteTag(tag);
int size = 0;
for (int i = 0; i >= -5; i--)
{
size += CodedOutputStream.ComputeEnumSize(i);
}
output.WriteRawVarint32((uint)size);
for (int i = 0; i >= -5; i--)
{
output.WriteEnum(i);
}
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = new CodedInputStream(bytes);
tag = input.ReadTag();
RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>();
values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x));
Assert.AreEqual(6, values.Count);
Assert.AreEqual(SampleEnum.None, values[0]);
Assert.AreEqual(((SampleEnum)(-1)), values[1]);
Assert.AreEqual(SampleEnum.NegativeValue, values[2]);
Assert.AreEqual(((SampleEnum)(-3)), values[3]);
Assert.AreEqual(((SampleEnum)(-4)), values[4]);
Assert.AreEqual(((SampleEnum)(-5)), values[5]);
}
// Fairly perfunctory tests for the non-generic IList implementation
[Test]
public void IList_Indexer()
{
var field = new RepeatedField<string> { "first", "second" };
IList list = field;
Assert.AreEqual("first", list[0]);
list[1] = "changed";
Assert.AreEqual("changed", field[1]);
}
[Test]
public void IList_Contains()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.IsTrue(list.Contains("second"));
Assert.IsFalse(list.Contains("third"));
Assert.IsFalse(list.Contains(new object()));
}
[Test]
public void IList_Add()
{
IList list = new RepeatedField<string> { "first", "second" };
list.Add("third");
CollectionAssert.AreEqual(new[] { "first", "second", "third" }, list);
}
[Test]
public void IList_Remove()
{
IList list = new RepeatedField<string> { "first", "second" };
list.Remove("third"); // No-op, no exception
list.Remove(new object()); // No-op, no exception
list.Remove("first");
CollectionAssert.AreEqual(new[] { "second" }, list);
}
[Test]
public void IList_IsFixedSize()
{
var field = new RepeatedField<string> { "first", "second" };
IList list = field;
Assert.IsFalse(list.IsFixedSize);
}
[Test]
public void IList_IndexOf()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.AreEqual(1, list.IndexOf("second"));
Assert.AreEqual(-1, list.IndexOf("third"));
Assert.AreEqual(-1, list.IndexOf(new object()));
}
[Test]
public void IList_SyncRoot()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.AreSame(list, list.SyncRoot);
}
[Test]
public void IList_CopyTo()
{
IList list = new RepeatedField<string> { "first", "second" };
string[] stringArray = new string[4];
list.CopyTo(stringArray, 1);
CollectionAssert.AreEqual(new[] { null, "first", "second", null }, stringArray);
object[] objectArray = new object[4];
list.CopyTo(objectArray, 1);
CollectionAssert.AreEqual(new[] { null, "first", "second", null }, objectArray);
Assert.Throws<ArrayTypeMismatchException>(() => list.CopyTo(new StringBuilder[4], 1));
Assert.Throws<ArrayTypeMismatchException>(() => list.CopyTo(new int[4], 1));
}
[Test]
public void IList_IsSynchronized()
{
IList list = new RepeatedField<string> { "first", "second" };
Assert.IsFalse(list.IsSynchronized);
}
[Test]
public void IList_Insert()
{
IList list = new RepeatedField<string> { "first", "second" };
list.Insert(1, "middle");
CollectionAssert.AreEqual(new[] { "first", "middle", "second" }, list);
}
[Test]
public void ToString_Integers()
{
var list = new RepeatedField<int> { 5, 10, 20 };
var text = list.ToString();
Assert.AreEqual("[ 5, 10, 20 ]", text);
}
[Test]
public void ToString_Strings()
{
var list = new RepeatedField<string> { "x", "y", "z" };
var text = list.ToString();
Assert.AreEqual("[ \"x\", \"y\", \"z\" ]", text);
}
[Test]
public void ToString_Messages()
{
var list = new RepeatedField<TestAllTypes> { new TestAllTypes { SingleDouble = 1.5 }, new TestAllTypes { SingleInt32 = 10 } };
var text = list.ToString();
Assert.AreEqual("[ { \"singleDouble\": 1.5 }, { \"singleInt32\": 10 } ]", text);
}
[Test]
public void ToString_Empty()
{
var list = new RepeatedField<TestAllTypes> { };
var text = list.ToString();
Assert.AreEqual("[ ]", text);
}
[Test]
public void ToString_InvalidElementType()
{
var list = new RepeatedField<decimal> { 15m };
Assert.Throws<ArgumentException>(() => list.ToString());
}
[Test]
public void ToString_Timestamp()
{
var list = new RepeatedField<Timestamp> { Timestamp.FromDateTime(new DateTime(2015, 10, 1, 12, 34, 56, DateTimeKind.Utc)) };
var text = list.ToString();
Assert.AreEqual("[ \"2015-10-01T12:34:56Z\" ]", text);
}
[Test]
public void ToString_Struct()
{
var message = new Struct { Fields = { { "foo", new Value { NumberValue = 20 } } } };
var list = new RepeatedField<Struct> { message };
var text = list.ToString();
Assert.AreEqual(text, "[ { \"foo\": 20 } ]", message.ToString());
}
}
}

View file

@ -0,0 +1,98 @@
#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 NUnit.Framework;
using System.Reflection;
namespace Google.Protobuf.Compatibility
{
public class PropertyInfoExtensionsTest
{
public string PublicReadWrite { get; set; }
private string PrivateReadWrite { get; set; }
public string PublicReadPrivateWrite { get; private set; }
public string PrivateReadPublicWrite { private get; set; }
public string PublicReadOnly { get { return null; } }
private string PrivateReadOnly { get { return null; } }
public string PublicWriteOnly { set { } }
private string PrivateWriteOnly { set { } }
[Test]
[TestCase("PublicReadWrite")]
[TestCase("PublicReadPrivateWrite")]
[TestCase("PublicReadOnly")]
public void GetGetMethod_Success(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNotNull(PropertyInfoExtensions.GetGetMethod(propertyInfo));
}
[Test]
[TestCase("PrivateReadWrite")]
[TestCase("PrivateReadPublicWrite")]
[TestCase("PrivateReadOnly")]
[TestCase("PublicWriteOnly")]
[TestCase("PrivateWriteOnly")]
public void GetGetMethod_NoAccessibleGetter(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNull(PropertyInfoExtensions.GetGetMethod(propertyInfo));
}
[Test]
[TestCase("PublicReadWrite")]
[TestCase("PrivateReadPublicWrite")]
[TestCase("PublicWriteOnly")]
public void GetSetMethod_Success(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNotNull(PropertyInfoExtensions.GetSetMethod(propertyInfo));
}
[Test]
[TestCase("PublicReadPrivateWrite")]
[TestCase("PrivateReadWrite")]
[TestCase("PrivateReadOnly")]
[TestCase("PublicReadOnly")]
[TestCase("PrivateWriteOnly")]
public void GetSetMethod_NoAccessibleGetter(string name)
{
var propertyInfo = typeof(PropertyInfoExtensionsTest)
.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
Assert.IsNull(PropertyInfoExtensions.GetSetMethod(propertyInfo));
}
}
}

View file

@ -0,0 +1,117 @@
#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 NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Reflection;
#if !DOTNET35
namespace Google.Protobuf.Compatibility
{
public class TypeExtensionsTest
{
public class DerivedList : List<string> { }
public string PublicProperty { get; set; }
private string PrivateProperty { get; set; }
public void PublicMethod()
{
}
private void PrivateMethod()
{
}
[Test]
[TestCase(typeof(object), typeof(string), true)]
[TestCase(typeof(object), typeof(int), true)]
[TestCase(typeof(string), typeof(string), true)]
[TestCase(typeof(string), typeof(object), false)]
[TestCase(typeof(string), typeof(int), false)]
[TestCase(typeof(int), typeof(int), true)]
[TestCase(typeof(ValueType), typeof(int), true)]
[TestCase(typeof(long), typeof(int), false)] //
public void IsAssignableFrom(Type target, Type argument, bool expected)
{
Assert.AreEqual(expected, TypeExtensions.IsAssignableFrom(target, argument));
}
[Test]
[TestCase(typeof(DerivedList), "Count")] // Go up the type hierarchy
[TestCase(typeof(List<string>), "Count")]
[TestCase(typeof(List<>), "Count")]
[TestCase(typeof(TypeExtensionsTest), "PublicProperty")]
public void GetProperty_Success(Type type, string name)
{
var property = TypeExtensions.GetProperty(type, name);
Assert.IsNotNull(property);
Assert.AreEqual(name, property.Name);
}
[Test]
[TestCase(typeof(TypeExtensionsTest), "PrivateProperty")]
[TestCase(typeof(TypeExtensionsTest), "Garbage")]
public void GetProperty_NoSuchProperty(Type type, string name)
{
var property = TypeExtensions.GetProperty(type, name);
Assert.IsNull(property);
}
[Test]
[TestCase(typeof(DerivedList), "RemoveAt")] // Go up the type hierarchy
[TestCase(typeof(List<>), "RemoveAt")]
[TestCase(typeof(TypeExtensionsTest), "PublicMethod")]
public void GetMethod_Success(Type type, string name)
{
var method = TypeExtensions.GetMethod(type, name);
Assert.IsNotNull(method);
Assert.AreEqual(name, method.Name);
}
[Test]
[TestCase(typeof(TypeExtensionsTest), "PrivateMethod")]
[TestCase(typeof(TypeExtensionsTest), "GarbageMethod")]
public void GetMethod_NoSuchMethod(Type type, string name)
{
var method = TypeExtensions.GetMethod(type, name);
Assert.IsNull(method);
}
[Test]
[TestCase(typeof(List<string>), "IndexOf")]
public void GetMethod_Ambiguous(Type type, string name)
{
Assert.Throws<AmbiguousMatchException>(() => TypeExtensions.GetMethod(type, name));
}
}
}
#endif

View file

@ -0,0 +1,55 @@
#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 System;
using System.Reflection;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class DeprecatedMemberTest
{
private static void AssertIsDeprecated(MemberInfo member)
{
Assert.NotNull(member);
Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);
}
[Test]
public void TestDepreatedPrimitiveValue()
{
AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
}
}
}

View file

@ -0,0 +1,64 @@
#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 System;
using NUnit.Framework;
namespace Google.Protobuf
{
/// <summary>
/// Helper methods when testing equality. NUnit's Assert.AreEqual and
/// Assert.AreNotEqual methods try to be clever with collections, which can
/// be annoying...
/// </summary>
internal static class EqualityTester
{
public static void AssertEquality<T>(T first, T second) where T : IEquatable<T>
{
Assert.IsTrue(first.Equals(second));
Assert.IsTrue(first.Equals((object) second));
Assert.AreEqual(first.GetHashCode(), second.GetHashCode());
}
public static void AssertInequality<T>(T first, T second) where T : IEquatable<T>
{
Assert.IsFalse(first.Equals(second));
Assert.IsFalse(first.Equals((object) second));
// While this isn't a requirement, the chances of this test failing due to
// coincidence rather than a bug are very small.
if (first != null && second != null)
{
Assert.AreNotEqual(first.GetHashCode(), second.GetHashCode());
}
}
}
}

View file

@ -0,0 +1,196 @@
#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 System.Collections.Generic;
using System.IO;
using System.Reflection;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class FieldCodecTest
{
#pragma warning disable 0414 // Used by tests via reflection - do not remove!
private static readonly List<ICodecTestData> Codecs = new List<ICodecTestData>
{
new FieldCodecTestData<bool>(FieldCodec.ForBool(100), true, "Bool"),
new FieldCodecTestData<string>(FieldCodec.ForString(100), "sample", "String"),
new FieldCodecTestData<ByteString>(FieldCodec.ForBytes(100), ByteString.CopyFrom(1, 2, 3), "Bytes"),
new FieldCodecTestData<int>(FieldCodec.ForInt32(100), -1000, "Int32"),
new FieldCodecTestData<int>(FieldCodec.ForSInt32(100), -1000, "SInt32"),
new FieldCodecTestData<int>(FieldCodec.ForSFixed32(100), -1000, "SFixed32"),
new FieldCodecTestData<uint>(FieldCodec.ForUInt32(100), 1234, "UInt32"),
new FieldCodecTestData<uint>(FieldCodec.ForFixed32(100), 1234, "Fixed32"),
new FieldCodecTestData<long>(FieldCodec.ForInt64(100), -1000, "Int64"),
new FieldCodecTestData<long>(FieldCodec.ForSInt64(100), -1000, "SInt64"),
new FieldCodecTestData<long>(FieldCodec.ForSFixed64(100), -1000, "SFixed64"),
new FieldCodecTestData<ulong>(FieldCodec.ForUInt64(100), 1234, "UInt64"),
new FieldCodecTestData<ulong>(FieldCodec.ForFixed64(100), 1234, "Fixed64"),
new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
new FieldCodecTestData<ForeignEnum>(
FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.ForeignBaz, "Enum"),
new FieldCodecTestData<ForeignMessage>(
FieldCodec.ForMessage(100, ForeignMessage.Parser), new ForeignMessage { C = 10 }, "Message"),
};
#pragma warning restore 0414
[Test, TestCaseSource("Codecs")]
public void RoundTripWithTag(ICodecTestData codec)
{
codec.TestRoundTripWithTag();
}
[Test, TestCaseSource("Codecs")]
public void RoundTripRaw(ICodecTestData codec)
{
codec.TestRoundTripRaw();
}
[Test, TestCaseSource("Codecs")]
public void CalculateSize(ICodecTestData codec)
{
codec.TestCalculateSizeWithTag();
}
[Test, TestCaseSource("Codecs")]
public void DefaultValue(ICodecTestData codec)
{
codec.TestDefaultValue();
}
[Test, TestCaseSource("Codecs")]
public void FixedSize(ICodecTestData codec)
{
codec.TestFixedSize();
}
// This is ugly, but it means we can have a non-generic interface.
// It feels like NUnit should support this better, but I don't know
// of any better ways right now.
public interface ICodecTestData
{
void TestRoundTripRaw();
void TestRoundTripWithTag();
void TestCalculateSizeWithTag();
void TestDefaultValue();
void TestFixedSize();
}
public class FieldCodecTestData<T> : ICodecTestData
{
private readonly FieldCodec<T> codec;
private readonly T sampleValue;
private readonly string name;
public FieldCodecTestData(FieldCodec<T> codec, T sampleValue, string name)
{
this.codec = codec;
this.sampleValue = sampleValue;
this.name = name;
}
public void TestRoundTripRaw()
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, sampleValue);
codedOutput.Flush();
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
Assert.AreEqual(sampleValue, codec.ValueReader(codedInput));
Assert.IsTrue(codedInput.IsAtEnd);
}
public void TestRoundTripWithTag()
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, sampleValue);
codedOutput.Flush();
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
codedInput.AssertNextTag(codec.Tag);
Assert.AreEqual(sampleValue, codec.Read(codedInput));
Assert.IsTrue(codedInput.IsAtEnd);
}
public void TestCalculateSizeWithTag()
{
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, sampleValue);
codedOutput.Flush();
Assert.AreEqual(stream.Position, codec.CalculateSizeWithTag(sampleValue));
}
public void TestDefaultValue()
{
// WriteTagAndValue ignores default values
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
codedOutput.Flush();
Assert.AreEqual(0, stream.Position);
Assert.AreEqual(0, codec.CalculateSizeWithTag(codec.DefaultValue));
if (typeof(T).GetTypeInfo().IsValueType)
{
Assert.AreEqual(default(T), codec.DefaultValue);
}
// The plain ValueWriter/ValueReader delegates don't.
if (codec.DefaultValue != null) // This part isn't appropriate for message types.
{
codedOutput = new CodedOutputStream(stream);
codec.ValueWriter(codedOutput, codec.DefaultValue);
codedOutput.Flush();
Assert.AreNotEqual(0, stream.Position);
Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue));
stream.Position = 0;
var codedInput = new CodedInputStream(stream);
Assert.AreEqual(codec.DefaultValue, codec.ValueReader(codedInput));
}
}
public void TestFixedSize()
{
Assert.AreEqual(name.Contains("Fixed"), codec.FixedSize != 0);
}
public override string ToString()
{
return name;
}
}
}
}

View file

@ -0,0 +1,723 @@
#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 System;
using System.IO;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Google.Protobuf.WellKnownTypes;
namespace Google.Protobuf
{
/// <summary>
/// Tests around the generated TestAllTypes message.
/// </summary>
public class GeneratedMessageTest
{
[Test]
public void EmptyMessageFieldDistinctFromMissingMessageField()
{
// This demonstrates what we're really interested in...
var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() };
var message2 = new TestAllTypes(); // SingleForeignMessage is null
EqualityTester.AssertInequality(message1, message2);
}
[Test]
public void DefaultValues()
{
// Single fields
var message = new TestAllTypes();
Assert.AreEqual(false, message.SingleBool);
Assert.AreEqual(ByteString.Empty, message.SingleBytes);
Assert.AreEqual(0.0, message.SingleDouble);
Assert.AreEqual(0, message.SingleFixed32);
Assert.AreEqual(0L, message.SingleFixed64);
Assert.AreEqual(0.0f, message.SingleFloat);
Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
Assert.IsNull(message.SingleForeignMessage);
Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
Assert.IsNull(message.SingleImportMessage);
Assert.AreEqual(0, message.SingleInt32);
Assert.AreEqual(0L, message.SingleInt64);
Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
Assert.IsNull(message.SingleNestedMessage);
Assert.IsNull(message.SinglePublicImportMessage);
Assert.AreEqual(0, message.SingleSfixed32);
Assert.AreEqual(0L, message.SingleSfixed64);
Assert.AreEqual(0, message.SingleSint32);
Assert.AreEqual(0L, message.SingleSint64);
Assert.AreEqual("", message.SingleString);
Assert.AreEqual(0U, message.SingleUint32);
Assert.AreEqual(0UL, message.SingleUint64);
// Repeated fields
Assert.AreEqual(0, message.RepeatedBool.Count);
Assert.AreEqual(0, message.RepeatedBytes.Count);
Assert.AreEqual(0, message.RepeatedDouble.Count);
Assert.AreEqual(0, message.RepeatedFixed32.Count);
Assert.AreEqual(0, message.RepeatedFixed64.Count);
Assert.AreEqual(0, message.RepeatedFloat.Count);
Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
Assert.AreEqual(0, message.RepeatedImportEnum.Count);
Assert.AreEqual(0, message.RepeatedImportMessage.Count);
Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
Assert.AreEqual(0, message.RepeatedPublicImportMessage.Count);
Assert.AreEqual(0, message.RepeatedSfixed32.Count);
Assert.AreEqual(0, message.RepeatedSfixed64.Count);
Assert.AreEqual(0, message.RepeatedSint32.Count);
Assert.AreEqual(0, message.RepeatedSint64.Count);
Assert.AreEqual(0, message.RepeatedString.Count);
Assert.AreEqual(0, message.RepeatedUint32.Count);
Assert.AreEqual(0, message.RepeatedUint64.Count);
// Oneof fields
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
}
[Test]
public void NullStringAndBytesRejected()
{
var message = new TestAllTypes();
Assert.Throws<ArgumentNullException>(() => message.SingleString = null);
Assert.Throws<ArgumentNullException>(() => message.OneofString = null);
Assert.Throws<ArgumentNullException>(() => message.SingleBytes = null);
Assert.Throws<ArgumentNullException>(() => message.OneofBytes = null);
}
[Test]
public void RoundTrip_Empty()
{
var message = new TestAllTypes();
// Without setting any values, there's nothing to write.
byte[] bytes = message.ToByteArray();
Assert.AreEqual(0, bytes.Length);
TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
[Test]
public void RoundTrip_SingleValues()
{
var message = new TestAllTypes
{
SingleBool = true,
SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
SingleDouble = 23.5,
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
SingleSint64 = -12345678901235,
SingleString = "test",
SingleUint32 = uint.MaxValue,
SingleUint64 = ulong.MaxValue
};
byte[] bytes = message.ToByteArray();
TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
[Test]
public void RoundTrip_RepeatedValues()
{
var message = new TestAllTypes
{
RepeatedBool = { true, false },
RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
RepeatedDouble = { -12.25, 23.5 },
RepeatedFixed32 = { uint.MaxValue, 23 },
RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
RepeatedSint64 = { -12345678901235, 123 },
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { uint.MaxValue, uint.MinValue },
RepeatedUint64 = { ulong.MaxValue, uint.MinValue }
};
byte[] bytes = message.ToByteArray();
TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
// Note that not every map within map_unittest_proto3 is used. They all go through very
// similar code paths. The fact that all maps are present is validation that we have codecs
// for every type.
[Test]
public void RoundTrip_Maps()
{
var message = new TestMap
{
MapBoolBool = {
{ false, true },
{ true, false }
},
MapInt32Bytes = {
{ 5, ByteString.CopyFrom(6, 7, 8) },
{ 25, ByteString.CopyFrom(1, 2, 3, 4, 5) },
{ 10, ByteString.Empty }
},
MapInt32ForeignMessage = {
{ 0, new ForeignMessage { C = 10 } },
{ 5, new ForeignMessage() },
},
MapInt32Enum = {
{ 1, MapEnum.Bar },
{ 2000, MapEnum.Foo }
}
};
byte[] bytes = message.ToByteArray();
TestMap parsed = TestMap.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
}
[Test]
public void MapWithEmptyEntry()
{
var message = new TestMap
{
MapInt32Bytes = { { 0, ByteString.Empty } }
};
byte[] bytes = message.ToByteArray();
Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)
var parsed = TestMap.Parser.ParseFrom(bytes);
Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
}
[Test]
public void MapWithOnlyValue()
{
// Hand-craft the stream to contain a single entry with just a value.
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
var nestedMessage = new ForeignMessage { C = 20 };
// Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
output.WriteLength(2 + nestedMessage.CalculateSize());
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteMessage(nestedMessage);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
}
[Test]
public void MapWithOnlyKey_PrimitiveValue()
{
// Hand-craft the stream to contain a single entry with just a key.
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
int key = 10;
output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
}
[Test]
public void MapWithOnlyKey_MessageValue()
{
// Hand-craft the stream to contain a single entry with just a key.
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
int key = 10;
output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
}
[Test]
public void MapIgnoresExtraFieldsWithinEntryMessages()
{
// Hand-craft the stream to contain a single entry with three fields
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
var key = 10; // Field 1
var value = 20; // Field 2
var extra = 30; // Field 3
// Each field can be represented in a single byte, with a single byte tag.
// Total message size: 6 bytes.
output.WriteLength(6);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value);
output.WriteTag(3, WireFormat.WireType.Varint);
output.WriteInt32(extra);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(value, parsed.MapInt32Int32[key]);
}
[Test]
public void MapFieldOrderIsIrrelevant()
{
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
var key = 10;
var value = 20;
// Each field can be represented in a single byte, with a single byte tag.
// Total message size: 4 bytes.
output.WriteLength(4);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(value, parsed.MapInt32Int32[key]);
}
[Test]
public void MapNonContiguousEntries()
{
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
// Message structure:
// Entry for MapInt32Int32
// Entry for MapStringString
// Entry for MapInt32Int32
// First entry
var key1 = 10;
var value1 = 20;
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key1);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value1);
// Second entry
var key2 = "a";
var value2 = "b";
output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(6); // 3 bytes per entry: tag, size, character
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
output.WriteString(key2);
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
output.WriteString(value2);
// Third entry
var key3 = 15;
var value3 = 25;
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key3);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value3);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
var expected = new TestMap
{
MapInt32Int32 = { { key1, value1 }, { key3, value3 } },
MapStringString = { { key2, value2 } }
};
Assert.AreEqual(expected, parsed);
}
[Test]
public void DuplicateKeys_LastEntryWins()
{
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
var key = 10;
var value1 = 20;
var value2 = 30;
// First entry
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value1);
// Second entry - same key, different value
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(4);
output.WriteTag(1, WireFormat.WireType.Varint);
output.WriteInt32(key);
output.WriteTag(2, WireFormat.WireType.Varint);
output.WriteInt32(value2);
output.Flush();
var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
}
[Test]
public void CloneSingleNonMessageValues()
{
var original = new TestAllTypes
{
SingleBool = true,
SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
SingleDouble = 23.5,
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
SingleInt32 = 100,
SingleInt64 = 3210987654321,
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
SingleSint64 = -12345678901235,
SingleString = "test",
SingleUint32 = uint.MaxValue,
SingleUint64 = ulong.MaxValue
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreEqual(original, clone);
// Just as a single example
clone.SingleInt32 = 150;
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneRepeatedNonMessageValues()
{
var original = new TestAllTypes
{
RepeatedBool = { true, false },
RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
RepeatedDouble = { -12.25, 23.5 },
RepeatedFixed32 = { uint.MaxValue, 23 },
RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
RepeatedSint64 = { -12345678901235, 123 },
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { uint.MaxValue, uint.MinValue },
RepeatedUint64 = { ulong.MaxValue, uint.MinValue }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreEqual(original, clone);
// Just as a single example
clone.RepeatedDouble.Add(25.5);
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneSingleMessageField()
{
var original = new TestAllTypes
{
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage);
Assert.AreEqual(original, clone);
clone.SingleNestedMessage.Bb = 30;
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneRepeatedMessageField()
{
var original = new TestAllTypes
{
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage);
Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]);
Assert.AreEqual(original, clone);
clone.RepeatedNestedMessage[0].Bb = 30;
Assert.AreNotEqual(original, clone);
}
[Test]
public void CloneOneofField()
{
var original = new TestAllTypes
{
OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
};
var clone = original.Clone();
Assert.AreNotSame(original, clone);
Assert.AreEqual(original, clone);
// We should have cloned the message
original.OneofNestedMessage.Bb = 30;
Assert.AreNotEqual(original, clone);
}
[Test]
public void OneofProperties()
{
// Switch the oneof case between each of the different options, and check everything behaves
// as expected in each case.
var message = new TestAllTypes();
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
message.OneofString = "sample";
Assert.AreEqual("sample", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase);
var bytes = ByteString.CopyFrom(1, 2, 3);
message.OneofBytes = bytes;
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(bytes, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofBytes, message.OneofFieldCase);
message.OneofUint32 = 20;
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(20, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message.OneofFieldCase);
var nestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 25 };
message.OneofNestedMessage = nestedMessage;
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.AreEqual(nestedMessage, message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofNestedMessage, message.OneofFieldCase);
message.ClearOneofField();
Assert.AreEqual("", message.OneofString);
Assert.AreEqual(0, message.OneofUint32);
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
Assert.IsNull(message.OneofNestedMessage);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
}
[Test]
public void Oneof_DefaultValuesNotEqual()
{
var message1 = new TestAllTypes { OneofString = "" };
var message2 = new TestAllTypes { OneofUint32 = 0 };
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message1.OneofFieldCase);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
Assert.AreNotEqual(message1, message2);
}
[Test]
public void OneofSerialization_NonDefaultValue()
{
var message = new TestAllTypes();
message.OneofString = "this would take a bit of space";
message.OneofUint32 = 10;
var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!
var message2 = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, message2);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
}
[Test]
public void OneofSerialization_DefaultValue()
{
var message = new TestAllTypes();
message.OneofString = "this would take a bit of space";
message.OneofUint32 = 0; // This is the default value for UInt32; normally wouldn't be serialized
var bytes = message.ToByteArray();
Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized
var message2 = TestAllTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, message2);
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
}
[Test]
public void IgnoreUnknownFields_RealDataStillRead()
{
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
var unusedFieldNumber = 23456;
Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteString("ignore me");
message.WriteTo(output);
output.Flush();
stream.Position = 0;
var parsed = TestAllTypes.Parser.ParseFrom(stream);
Assert.AreEqual(message, parsed);
}
[Test]
public void IgnoreUnknownFields_AllTypes()
{
// Simple way of ensuring we can skip all kinds of fields.
var data = SampleMessages.CreateFullTestAllTypes().ToByteArray();
var empty = Empty.Parser.ParseFrom(data);
Assert.AreEqual(new Empty(), empty);
}
// This was originally seen as a conformance test failure.
[Test]
public void TruncatedMessageFieldThrows()
{
// 130, 3 is the message tag
// 1 is the data length - but there's no data.
var data = new byte[] { 130, 3, 1 };
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
}
/// <summary>
/// Demonstrates current behaviour with an extraneous end group tag - see issue 688
/// for details; we may want to change this.
/// </summary>
[Test]
public void ExtraEndGroupThrows()
{
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
output.WriteFixed32(123);
output.WriteTag(100, WireFormat.WireType.EndGroup);
output.Flush();
stream.Position = 0;
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream));
}
[Test]
public void CustomDiagnosticMessage_DirectToStringCall()
{
var message = new ForeignMessage { C = 31 };
Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
}
[Test]
public void CustomDiagnosticMessage_Nested()
{
var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
}
[Test]
public void CustomDiagnosticMessage_DirectToTextWriterCall()
{
var message = new ForeignMessage { C = 31 };
var writer = new StringWriter();
JsonFormatter.Default.Format(message, writer);
Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
}
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>580eb013-d3c7-4578-b845-015f4a3b0591</ProjectGuid>
<RootNamespace>Google.Protobuf.Test</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,82 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.Reflection;
using UnitTest.Issues.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
/// <summary>
/// Tests for issues which aren't easily compartmentalized into other unit tests.
/// </summary>
public class IssuesTest
{
// Issue 45
[Test]
public void FieldCalledItem()
{
ItemField message = new ItemField { Item = 3 };
FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
Assert.NotNull(field);
Assert.AreEqual(3, (int)field.Accessor.GetValue(message));
}
[Test]
public void ReservedNames()
{
var message = new ReservedNames { Types_ = 10, Descriptor_ = 20 };
// Underscores aren't reflected in the JSON.
Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
}
[Test]
public void JsonNameParseTest()
{
var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
var parser = new JsonParser(settings);
// It is safe to use either original field name or explicitly specified json_name
Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
}
[Test]
public void JsonNameFormatTest()
{
var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
JsonFormatter.Default.Format(message));
}
}
}

View file

@ -0,0 +1,939 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.Reflection;
using Google.Protobuf.TestProtos;
using Google.Protobuf.WellKnownTypes;
using NUnit.Framework;
using System;
namespace Google.Protobuf
{
/// <summary>
/// Unit tests for JSON parsing.
/// </summary>
public class JsonParserTest
{
// Sanity smoke test
[Test]
public void AllTypesRoundtrip()
{
AssertRoundtrip(SampleMessages.CreateFullTestAllTypes());
}
[Test]
public void Maps()
{
AssertRoundtrip(new TestMap { MapStringString = { { "with spaces", "bar" }, { "a", "b" } } });
AssertRoundtrip(new TestMap { MapInt32Int32 = { { 0, 1 }, { 2, 3 } } });
AssertRoundtrip(new TestMap { MapBoolBool = { { false, true }, { true, false } } });
}
[Test]
[TestCase(" 1 ")]
[TestCase("+1")]
[TestCase("1,000")]
[TestCase("1.5")]
public void IntegerMapKeysAreStrict(string keyText)
{
// Test that integer parsing is strict. We assume that if this is correct for int32,
// it's correct for other numeric key types.
var json = "{ \"mapInt32Int32\": { \"" + keyText + "\" : \"1\" } }";
Assert.Throws<InvalidProtocolBufferException>(() => JsonParser.Default.Parse<TestMap>(json));
}
[Test]
public void OriginalFieldNameAccepted()
{
var json = "{ \"single_int32\": 10 }";
var expected = new TestAllTypes { SingleInt32 = 10 };
Assert.AreEqual(expected, TestAllTypes.Parser.ParseJson(json));
}
[Test]
public void SourceContextRoundtrip()
{
AssertRoundtrip(new SourceContext { FileName = "foo.proto" });
}
[Test]
public void SingularWrappers_DefaultNonNullValues()
{
var message = new TestWellKnownTypes
{
StringField = "",
BytesField = ByteString.Empty,
BoolField = false,
FloatField = 0f,
DoubleField = 0d,
Int32Field = 0,
Int64Field = 0,
Uint32Field = 0,
Uint64Field = 0
};
AssertRoundtrip(message);
}
[Test]
public void SingularWrappers_NonDefaultValues()
{
var message = new TestWellKnownTypes
{
StringField = "x",
BytesField = ByteString.CopyFrom(1, 2, 3),
BoolField = true,
FloatField = 12.5f,
DoubleField = 12.25d,
Int32Field = 1,
Int64Field = 2,
Uint32Field = 3,
Uint64Field = 4
};
AssertRoundtrip(message);
}
[Test]
public void SingularWrappers_ExplicitNulls()
{
// When we parse the "valueField": null part, we remember it... basically, it's one case
// where explicit default values don't fully roundtrip.
var message = new TestWellKnownTypes { ValueField = Value.ForNull() };
var json = new JsonFormatter(new JsonFormatter.Settings(true)).Format(message);
var parsed = JsonParser.Default.Parse<TestWellKnownTypes>(json);
Assert.AreEqual(message, parsed);
}
[Test]
[TestCase(typeof(BoolValue), "true", true)]
[TestCase(typeof(Int32Value), "32", 32)]
[TestCase(typeof(Int64Value), "32", 32L)]
[TestCase(typeof(Int64Value), "\"32\"", 32L)]
[TestCase(typeof(UInt32Value), "32", 32U)]
[TestCase(typeof(UInt64Value), "\"32\"", 32UL)]
[TestCase(typeof(UInt64Value), "32", 32UL)]
[TestCase(typeof(StringValue), "\"foo\"", "foo")]
[TestCase(typeof(FloatValue), "1.5", 1.5f)]
[TestCase(typeof(DoubleValue), "1.5", 1.5d)]
public void Wrappers_Standalone(System.Type wrapperType, string json, object expectedValue)
{
IMessage parsed = (IMessage)Activator.CreateInstance(wrapperType);
IMessage expected = (IMessage)Activator.CreateInstance(wrapperType);
JsonParser.Default.Merge(parsed, "null");
Assert.AreEqual(expected, parsed);
JsonParser.Default.Merge(parsed, json);
expected.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.SetValue(expected, expectedValue);
Assert.AreEqual(expected, parsed);
}
[Test]
public void ExplicitNullValue()
{
string json = "{\"valueField\": null}";
var message = JsonParser.Default.Parse<TestWellKnownTypes>(json);
Assert.AreEqual(new TestWellKnownTypes { ValueField = Value.ForNull() }, message);
}
[Test]
public void BytesWrapper_Standalone()
{
ByteString data = ByteString.CopyFrom(1, 2, 3);
// Can't do this with attributes...
var parsed = JsonParser.Default.Parse<BytesValue>(WrapInQuotes(data.ToBase64()));
var expected = new BytesValue { Value = data };
Assert.AreEqual(expected, parsed);
}
[Test]
public void RepeatedWrappers()
{
var message = new RepeatedWellKnownTypes
{
BoolField = { true, false },
BytesField = { ByteString.CopyFrom(1, 2, 3), ByteString.CopyFrom(4, 5, 6), ByteString.Empty },
DoubleField = { 12.5, -1.5, 0d },
FloatField = { 123.25f, -20f, 0f },
Int32Field = { int.MaxValue, int.MinValue, 0 },
Int64Field = { long.MaxValue, long.MinValue, 0L },
StringField = { "First", "Second", "" },
Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
};
AssertRoundtrip(message);
}
[Test]
public void RepeatedField_NullElementProhibited()
{
string json = "{ \"repeated_foreign_message\": [null] }";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
public void RepeatedField_NullOverallValueAllowed()
{
string json = "{ \"repeated_foreign_message\": null }";
Assert.AreEqual(new TestAllTypes(), TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("{ \"mapInt32Int32\": { \"10\": null }")]
[TestCase("{ \"mapStringString\": { \"abc\": null }")]
[TestCase("{ \"mapInt32ForeignMessage\": { \"10\": null }")]
public void MapField_NullValueProhibited(string json)
{
Assert.Throws<InvalidProtocolBufferException>(() => TestMap.Parser.ParseJson(json));
}
[Test]
public void MapField_NullOverallValueAllowed()
{
string json = "{ \"mapInt32Int32\": null }";
Assert.AreEqual(new TestMap(), TestMap.Parser.ParseJson(json));
}
[Test]
public void IndividualWrapperTypes()
{
Assert.AreEqual(new StringValue { Value = "foo" }, StringValue.Parser.ParseJson("\"foo\""));
Assert.AreEqual(new Int32Value { Value = 1 }, Int32Value.Parser.ParseJson("1"));
// Can parse strings directly too
Assert.AreEqual(new Int32Value { Value = 1 }, Int32Value.Parser.ParseJson("\"1\""));
}
private static void AssertRoundtrip<T>(T message) where T : IMessage<T>, new()
{
var clone = message.Clone();
var json = JsonFormatter.Default.Format(message);
var parsed = JsonParser.Default.Parse<T>(json);
Assert.AreEqual(clone, parsed);
}
[Test]
[TestCase("0", 0)]
[TestCase("-0", 0)] // Not entirely clear whether we intend to allow this...
[TestCase("1", 1)]
[TestCase("-1", -1)]
[TestCase("2147483647", 2147483647)]
[TestCase("-2147483648", -2147483648)]
public void StringToInt32_Valid(string jsonValue, int expectedParsedValue)
{
string json = "{ \"singleInt32\": \"" + jsonValue + "\"}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleInt32);
}
[Test]
[TestCase("+0")]
[TestCase(" 1")]
[TestCase("1 ")]
[TestCase("00")]
[TestCase("-00")]
[TestCase("--1")]
[TestCase("+1")]
[TestCase("1.5")]
[TestCase("1e10")]
[TestCase("2147483648")]
[TestCase("-2147483649")]
public void StringToInt32_Invalid(string jsonValue)
{
string json = "{ \"singleInt32\": \"" + jsonValue + "\"}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0U)]
[TestCase("1", 1U)]
[TestCase("4294967295", 4294967295U)]
public void StringToUInt32_Valid(string jsonValue, uint expectedParsedValue)
{
string json = "{ \"singleUint32\": \"" + jsonValue + "\"}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleUint32);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
[TestCase("-1")]
[TestCase("4294967296")]
public void StringToUInt32_Invalid(string jsonValue)
{
string json = "{ \"singleUint32\": \"" + jsonValue + "\"}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0L)]
[TestCase("1", 1L)]
[TestCase("-1", -1L)]
[TestCase("9223372036854775807", 9223372036854775807)]
[TestCase("-9223372036854775808", -9223372036854775808)]
public void StringToInt64_Valid(string jsonValue, long expectedParsedValue)
{
string json = "{ \"singleInt64\": \"" + jsonValue + "\"}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleInt64);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
[TestCase("-9223372036854775809")]
[TestCase("9223372036854775808")]
public void StringToInt64_Invalid(string jsonValue)
{
string json = "{ \"singleInt64\": \"" + jsonValue + "\"}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0UL)]
[TestCase("1", 1UL)]
[TestCase("18446744073709551615", 18446744073709551615)]
public void StringToUInt64_Valid(string jsonValue, ulong expectedParsedValue)
{
string json = "{ \"singleUint64\": \"" + jsonValue + "\"}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleUint64);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
[TestCase("-1")]
[TestCase("18446744073709551616")]
public void StringToUInt64_Invalid(string jsonValue)
{
string json = "{ \"singleUint64\": \"" + jsonValue + "\"}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0d)]
[TestCase("1", 1d)]
[TestCase("1.000000", 1d)]
[TestCase("1.0000000000000000000000001", 1d)] // We don't notice that we haven't preserved the exact value
[TestCase("-1", -1d)]
[TestCase("1e1", 10d)]
[TestCase("1e01", 10d)] // Leading decimals are allowed in exponents
[TestCase("1E1", 10d)] // Either case is fine
[TestCase("-1e1", -10d)]
[TestCase("1.5e1", 15d)]
[TestCase("-1.5e1", -15d)]
[TestCase("15e-1", 1.5d)]
[TestCase("-15e-1", -1.5d)]
[TestCase("1.79769e308", 1.79769e308)]
[TestCase("-1.79769e308", -1.79769e308)]
[TestCase("Infinity", double.PositiveInfinity)]
[TestCase("-Infinity", double.NegativeInfinity)]
[TestCase("NaN", double.NaN)]
public void StringToDouble_Valid(string jsonValue, double expectedParsedValue)
{
string json = "{ \"singleDouble\": \"" + jsonValue + "\"}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleDouble);
}
[Test]
[TestCase("1.7977e308")]
[TestCase("-1.7977e308")]
[TestCase("1e309")]
[TestCase("1,0")]
[TestCase("1.0.0")]
[TestCase("+1")]
[TestCase("00")]
[TestCase("01")]
[TestCase("-00")]
[TestCase("-01")]
[TestCase("--1")]
[TestCase(" Infinity")]
[TestCase(" -Infinity")]
[TestCase("NaN ")]
[TestCase("Infinity ")]
[TestCase("-Infinity ")]
[TestCase(" NaN")]
[TestCase("INFINITY")]
[TestCase("nan")]
[TestCase("\u00BD")] // 1/2 as a single Unicode character. Just sanity checking...
public void StringToDouble_Invalid(string jsonValue)
{
string json = "{ \"singleDouble\": \"" + jsonValue + "\"}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0f)]
[TestCase("1", 1f)]
[TestCase("1.000000", 1f)]
[TestCase("-1", -1f)]
[TestCase("3.402823e38", 3.402823e38f)]
[TestCase("-3.402823e38", -3.402823e38f)]
[TestCase("1.5e1", 15f)]
[TestCase("15e-1", 1.5f)]
public void StringToFloat_Valid(string jsonValue, float expectedParsedValue)
{
string json = "{ \"singleFloat\": \"" + jsonValue + "\"}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleFloat);
}
[Test]
[TestCase("3.402824e38")]
[TestCase("-3.402824e38")]
[TestCase("1,0")]
[TestCase("1.0.0")]
[TestCase("+1")]
[TestCase("00")]
[TestCase("--1")]
public void StringToFloat_Invalid(string jsonValue)
{
string json = "{ \"singleFloat\": \"" + jsonValue + "\"}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0)]
[TestCase("-0", 0)] // Not entirely clear whether we intend to allow this...
[TestCase("1", 1)]
[TestCase("-1", -1)]
[TestCase("2147483647", 2147483647)]
[TestCase("-2147483648", -2147483648)]
[TestCase("1e1", 10)]
[TestCase("-1e1", -10)]
[TestCase("10.00", 10)]
[TestCase("-10.00", -10)]
public void NumberToInt32_Valid(string jsonValue, int expectedParsedValue)
{
string json = "{ \"singleInt32\": " + jsonValue + "}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleInt32);
}
[Test]
[TestCase("+0", typeof(InvalidJsonException))]
[TestCase("00", typeof(InvalidJsonException))]
[TestCase("-00", typeof(InvalidJsonException))]
[TestCase("--1", typeof(InvalidJsonException))]
[TestCase("+1", typeof(InvalidJsonException))]
[TestCase("1.5", typeof(InvalidProtocolBufferException))]
// Value is out of range
[TestCase("1e10", typeof(InvalidProtocolBufferException))]
[TestCase("2147483648", typeof(InvalidProtocolBufferException))]
[TestCase("-2147483649", typeof(InvalidProtocolBufferException))]
public void NumberToInt32_Invalid(string jsonValue, System.Type expectedExceptionType)
{
string json = "{ \"singleInt32\": " + jsonValue + "}";
Assert.Throws(expectedExceptionType, () => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0U)]
[TestCase("1", 1U)]
[TestCase("4294967295", 4294967295U)]
public void NumberToUInt32_Valid(string jsonValue, uint expectedParsedValue)
{
string json = "{ \"singleUint32\": " + jsonValue + "}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleUint32);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
[TestCase("-1")]
[TestCase("4294967296")]
public void NumberToUInt32_Invalid(string jsonValue)
{
string json = "{ \"singleUint32\": " + jsonValue + "}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0L)]
[TestCase("1", 1L)]
[TestCase("-1", -1L)]
// long.MaxValue isn't actually representable as a double. This string value is the highest
// representable value which isn't greater than long.MaxValue.
[TestCase("9223372036854774784", 9223372036854774784)]
[TestCase("-9223372036854775808", -9223372036854775808)]
public void NumberToInt64_Valid(string jsonValue, long expectedParsedValue)
{
string json = "{ \"singleInt64\": " + jsonValue + "}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleInt64);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
[TestCase("9223372036854775808")]
// Theoretical bound would be -9223372036854775809, but when that is parsed to a double
// we end up with the exact value of long.MinValue due to lack of precision. The value here
// is the "next double down".
[TestCase("-9223372036854780000")]
public void NumberToInt64_Invalid(string jsonValue)
{
string json = "{ \"singleInt64\": " + jsonValue + "}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0UL)]
[TestCase("1", 1UL)]
// ulong.MaxValue isn't representable as a double. This value is the largest double within
// the range of ulong.
[TestCase("18446744073709549568", 18446744073709549568UL)]
public void NumberToUInt64_Valid(string jsonValue, ulong expectedParsedValue)
{
string json = "{ \"singleUint64\": " + jsonValue + "}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleUint64);
}
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
[TestCase("-1")]
[TestCase("18446744073709551616")]
public void NumberToUInt64_Invalid(string jsonValue)
{
string json = "{ \"singleUint64\": " + jsonValue + "}";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0d)]
[TestCase("1", 1d)]
[TestCase("1.000000", 1d)]
[TestCase("1.0000000000000000000000001", 1d)] // We don't notice that we haven't preserved the exact value
[TestCase("-1", -1d)]
[TestCase("1e1", 10d)]
[TestCase("1e01", 10d)] // Leading decimals are allowed in exponents
[TestCase("1E1", 10d)] // Either case is fine
[TestCase("-1e1", -10d)]
[TestCase("1.5e1", 15d)]
[TestCase("-1.5e1", -15d)]
[TestCase("15e-1", 1.5d)]
[TestCase("-15e-1", -1.5d)]
[TestCase("1.79769e308", 1.79769e308)]
[TestCase("-1.79769e308", -1.79769e308)]
public void NumberToDouble_Valid(string jsonValue, double expectedParsedValue)
{
string json = "{ \"singleDouble\": " + jsonValue + "}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleDouble);
}
[Test]
[TestCase("1.7977e308")]
[TestCase("-1.7977e308")]
[TestCase("1e309")]
[TestCase("1,0")]
[TestCase("1.0.0")]
[TestCase("+1")]
[TestCase("00")]
[TestCase("--1")]
[TestCase("\u00BD")] // 1/2 as a single Unicode character. Just sanity checking...
public void NumberToDouble_Invalid(string jsonValue)
{
string json = "{ \"singleDouble\": " + jsonValue + "}";
Assert.Throws<InvalidJsonException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("0", 0f)]
[TestCase("1", 1f)]
[TestCase("1.000000", 1f)]
[TestCase("-1", -1f)]
[TestCase("3.402823e38", 3.402823e38f)]
[TestCase("-3.402823e38", -3.402823e38f)]
[TestCase("1.5e1", 15f)]
[TestCase("15e-1", 1.5f)]
public void NumberToFloat_Valid(string jsonValue, float expectedParsedValue)
{
string json = "{ \"singleFloat\": " + jsonValue + "}";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(expectedParsedValue, parsed.SingleFloat);
}
[Test]
[TestCase("3.402824e38", typeof(InvalidProtocolBufferException))]
[TestCase("-3.402824e38", typeof(InvalidProtocolBufferException))]
[TestCase("1,0", typeof(InvalidJsonException))]
[TestCase("1.0.0", typeof(InvalidJsonException))]
[TestCase("+1", typeof(InvalidJsonException))]
[TestCase("00", typeof(InvalidJsonException))]
[TestCase("--1", typeof(InvalidJsonException))]
public void NumberToFloat_Invalid(string jsonValue, System.Type expectedExceptionType)
{
string json = "{ \"singleFloat\": " + jsonValue + "}";
Assert.Throws(expectedExceptionType, () => TestAllTypes.Parser.ParseJson(json));
}
// The simplest way of testing that the value has parsed correctly is to reformat it,
// as we trust the formatting. In many cases that will give the same result as the input,
// so in those cases we accept an expectedFormatted value of null. Sometimes the results
// will be different though, due to a different number of digits being provided.
[Test]
// Z offset
[TestCase("2015-10-09T14:46:23.123456789Z", null)]
[TestCase("2015-10-09T14:46:23.123456Z", null)]
[TestCase("2015-10-09T14:46:23.123Z", null)]
[TestCase("2015-10-09T14:46:23Z", null)]
[TestCase("2015-10-09T14:46:23.123456000Z", "2015-10-09T14:46:23.123456Z")]
[TestCase("2015-10-09T14:46:23.1234560Z", "2015-10-09T14:46:23.123456Z")]
[TestCase("2015-10-09T14:46:23.123000000Z", "2015-10-09T14:46:23.123Z")]
[TestCase("2015-10-09T14:46:23.1230Z", "2015-10-09T14:46:23.123Z")]
[TestCase("2015-10-09T14:46:23.00Z", "2015-10-09T14:46:23Z")]
// +00:00 offset
[TestCase("2015-10-09T14:46:23.123456789+00:00", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-09T14:46:23.123456+00:00", "2015-10-09T14:46:23.123456Z")]
[TestCase("2015-10-09T14:46:23.123+00:00", "2015-10-09T14:46:23.123Z")]
[TestCase("2015-10-09T14:46:23+00:00", "2015-10-09T14:46:23Z")]
[TestCase("2015-10-09T14:46:23.123456000+00:00", "2015-10-09T14:46:23.123456Z")]
[TestCase("2015-10-09T14:46:23.1234560+00:00", "2015-10-09T14:46:23.123456Z")]
[TestCase("2015-10-09T14:46:23.123000000+00:00", "2015-10-09T14:46:23.123Z")]
[TestCase("2015-10-09T14:46:23.1230+00:00", "2015-10-09T14:46:23.123Z")]
[TestCase("2015-10-09T14:46:23.00+00:00", "2015-10-09T14:46:23Z")]
// Other offsets (assume by now that the subsecond handling is okay)
[TestCase("2015-10-09T15:46:23.123456789+01:00", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-09T13:46:23.123456789-01:00", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-09T15:16:23.123456789+00:30", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-09T14:16:23.123456789-00:30", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-09T16:31:23.123456789+01:45", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-09T13:01:23.123456789-01:45", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-10T08:46:23.123456789+18:00", "2015-10-09T14:46:23.123456789Z")]
[TestCase("2015-10-08T20:46:23.123456789-18:00", "2015-10-09T14:46:23.123456789Z")]
// Leap years and min/max
[TestCase("2016-02-29T14:46:23.123456789Z", null)]
[TestCase("2000-02-29T14:46:23.123456789Z", null)]
[TestCase("0001-01-01T00:00:00Z", null)]
[TestCase("9999-12-31T23:59:59.999999999Z", null)]
public void Timestamp_Valid(string jsonValue, string expectedFormatted)
{
expectedFormatted = expectedFormatted ?? jsonValue;
string json = WrapInQuotes(jsonValue);
var parsed = Timestamp.Parser.ParseJson(json);
Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
}
[Test]
[TestCase("2015-10-09 14:46:23.123456789Z", Description = "No T between date and time")]
[TestCase("2015/10/09T14:46:23.123456789Z", Description = "Wrong date separators")]
[TestCase("2015-10-09T14.46.23.123456789Z", Description = "Wrong time separators")]
[TestCase("2015-10-09T14:46:23,123456789Z", Description = "Wrong fractional second separators (valid ISO-8601 though)")]
[TestCase(" 2015-10-09T14:46:23.123456789Z", Description = "Whitespace at start")]
[TestCase("2015-10-09T14:46:23.123456789Z ", Description = "Whitespace at end")]
[TestCase("2015-10-09T14:46:23.1234567890", Description = "Too many digits")]
[TestCase("2015-10-09T14:46:23.123456789", Description = "No offset")]
[TestCase("2015-13-09T14:46:23.123456789Z", Description = "Invalid month")]
[TestCase("2015-10-32T14:46:23.123456789Z", Description = "Invalid day")]
[TestCase("2015-10-09T24:00:00.000000000Z", Description = "Invalid hour (valid ISO-8601 though)")]
[TestCase("2015-10-09T14:60:23.123456789Z", Description = "Invalid minutes")]
[TestCase("2015-10-09T14:46:60.123456789Z", Description = "Invalid seconds")]
[TestCase("2015-10-09T14:46:23.123456789+18:01", Description = "Offset too large (positive)")]
[TestCase("2015-10-09T14:46:23.123456789-18:01", Description = "Offset too large (negative)")]
[TestCase("2015-10-09T14:46:23.123456789-00:00", Description = "Local offset (-00:00) makes no sense here")]
[TestCase("0001-01-01T00:00:00+00:01", Description = "Value before earliest when offset applied")]
[TestCase("9999-12-31T23:59:59.999999999-00:01", Description = "Value after latest when offset applied")]
[TestCase("2100-02-29T14:46:23.123456789Z", Description = "Feb 29th on a non-leap-year")]
public void Timestamp_Invalid(string jsonValue)
{
string json = WrapInQuotes(jsonValue);
Assert.Throws<InvalidProtocolBufferException>(() => Timestamp.Parser.ParseJson(json));
}
[Test]
public void StructValue_Null()
{
Assert.AreEqual(new Value { NullValue = 0 }, Value.Parser.ParseJson("null"));
}
[Test]
public void StructValue_String()
{
Assert.AreEqual(new Value { StringValue = "hi" }, Value.Parser.ParseJson("\"hi\""));
}
[Test]
public void StructValue_Bool()
{
Assert.AreEqual(new Value { BoolValue = true }, Value.Parser.ParseJson("true"));
Assert.AreEqual(new Value { BoolValue = false }, Value.Parser.ParseJson("false"));
}
[Test]
public void StructValue_List()
{
Assert.AreEqual(Value.ForList(Value.ForNumber(1), Value.ForString("x")), Value.Parser.ParseJson("[1, \"x\"]"));
}
[Test]
public void ParseListValue()
{
Assert.AreEqual(new ListValue { Values = { Value.ForNumber(1), Value.ForString("x") } }, ListValue.Parser.ParseJson("[1, \"x\"]"));
}
[Test]
public void StructValue_Struct()
{
Assert.AreEqual(
Value.ForStruct(new Struct { Fields = { { "x", Value.ForNumber(1) }, { "y", Value.ForString("z") } } }),
Value.Parser.ParseJson("{ \"x\": 1, \"y\": \"z\" }"));
}
[Test]
public void ParseStruct()
{
Assert.AreEqual(new Struct { Fields = { { "x", Value.ForNumber(1) }, { "y", Value.ForString("z") } } },
Struct.Parser.ParseJson("{ \"x\": 1, \"y\": \"z\" }"));
}
// TODO for duration parsing: upper and lower bounds.
// +/- 315576000000 seconds
[Test]
[TestCase("1.123456789s", null)]
[TestCase("1.123456s", null)]
[TestCase("1.123s", null)]
[TestCase("1.12300s", "1.123s")]
[TestCase("1.12345s", "1.123450s")]
[TestCase("1s", null)]
[TestCase("-1.123456789s", null)]
[TestCase("-1.123456s", null)]
[TestCase("-1.123s", null)]
[TestCase("-1s", null)]
[TestCase("0.123s", null)]
[TestCase("-0.123s", null)]
[TestCase("123456.123s", null)]
[TestCase("-123456.123s", null)]
// Upper and lower bounds
[TestCase("315576000000s", null)]
[TestCase("-315576000000s", null)]
public void Duration_Valid(string jsonValue, string expectedFormatted)
{
expectedFormatted = expectedFormatted ?? jsonValue;
string json = WrapInQuotes(jsonValue);
var parsed = Duration.Parser.ParseJson(json);
Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
}
// The simplest way of testing that the value has parsed correctly is to reformat it,
// as we trust the formatting. In many cases that will give the same result as the input,
// so in those cases we accept an expectedFormatted value of null. Sometimes the results
// will be different though, due to a different number of digits being provided.
[Test]
[TestCase("1.1234567890s", Description = "Too many digits")]
[TestCase("1.123456789", Description = "No suffix")]
[TestCase("1.123456789ss", Description = "Too much suffix")]
[TestCase("1.123456789S", Description = "Upper case suffix")]
[TestCase("+1.123456789s", Description = "Leading +")]
[TestCase(".123456789s", Description = "No integer before the fraction")]
[TestCase("1,123456789s", Description = "Comma as decimal separator")]
[TestCase("1x1.123456789s", Description = "Non-digit in integer part")]
[TestCase("1.1x3456789s", Description = "Non-digit in fractional part")]
[TestCase(" 1.123456789s", Description = "Whitespace before fraction")]
[TestCase("1.123456789s ", Description = "Whitespace after value")]
[TestCase("01.123456789s", Description = "Leading zero (positive)")]
[TestCase("-01.123456789s", Description = "Leading zero (negative)")]
[TestCase("--0.123456789s", Description = "Double minus sign")]
// Violate upper/lower bounds in various ways
[TestCase("315576000001s", Description = "Integer part too large")]
[TestCase("3155760000000s", Description = "Integer part too long (positive)")]
[TestCase("-3155760000000s", Description = "Integer part too long (negative)")]
public void Duration_Invalid(string jsonValue)
{
string json = WrapInQuotes(jsonValue);
Assert.Throws<InvalidProtocolBufferException>(() => Duration.Parser.ParseJson(json));
}
// Not as many tests for field masks as I'd like; more to be added when we have more
// detailed specifications.
[Test]
[TestCase("")]
[TestCase("foo", "foo")]
[TestCase("foo,bar", "foo", "bar")]
[TestCase("foo.bar", "foo.bar")]
[TestCase("fooBar", "foo_bar")]
[TestCase("fooBar.bazQux", "foo_bar.baz_qux")]
public void FieldMask_Valid(string jsonValue, params string[] expectedPaths)
{
string json = WrapInQuotes(jsonValue);
var parsed = FieldMask.Parser.ParseJson(json);
CollectionAssert.AreEqual(expectedPaths, parsed.Paths);
}
[Test]
[TestCase("foo_bar")]
public void FieldMask_Invalid(string jsonValue)
{
string json = WrapInQuotes(jsonValue);
Assert.Throws<InvalidProtocolBufferException>(() => FieldMask.Parser.ParseJson(json));
}
[Test]
public void Any_RegularMessage()
{
var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } };
var original = Any.Pack(message);
var json = formatter.Format(original); // This is tested in JsonFormatterTest
var parser = new JsonParser(new JsonParser.Settings(10, registry));
Assert.AreEqual(original, parser.Parse<Any>(json));
string valueFirstJson = "{ \"singleInt32\": 10, \"singleNestedMessage\": { \"bb\": 20 }, \"@type\": \"type.googleapis.com/protobuf_unittest.TestAllTypes\" }";
Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
}
[Test]
public void Any_CustomPrefix()
{
var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
var message = new TestAllTypes { SingleInt32 = 10 };
var original = Any.Pack(message, "custom.prefix/middle-part");
var parser = new JsonParser(new JsonParser.Settings(10, registry));
string json = "{ \"@type\": \"custom.prefix/middle-part/protobuf_unittest.TestAllTypes\", \"singleInt32\": 10 }";
Assert.AreEqual(original, parser.Parse<Any>(json));
}
[Test]
public void Any_UnknownType()
{
string json = "{ \"@type\": \"type.googleapis.com/bogus\" }";
Assert.Throws<InvalidOperationException>(() => Any.Parser.ParseJson(json));
}
[Test]
public void Any_NoTypeUrl()
{
string json = "{ \"foo\": \"bar\" }";
Assert.Throws<InvalidProtocolBufferException>(() => Any.Parser.ParseJson(json));
}
[Test]
public void Any_WellKnownType()
{
var registry = TypeRegistry.FromMessages(Timestamp.Descriptor);
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
var original = Any.Pack(timestamp);
var json = formatter.Format(original); // This is tested in JsonFormatterTest
var parser = new JsonParser(new JsonParser.Settings(10, registry));
Assert.AreEqual(original, parser.Parse<Any>(json));
string valueFirstJson = "{ \"value\": \"1673-06-19T12:34:56Z\", \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\" }";
Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
}
[Test]
public void Any_Nested()
{
var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor);
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
var parser = new JsonParser(new JsonParser.Settings(10, registry));
var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 };
var nestedMessage = Any.Pack(doubleNestedMessage);
var message = new TestWellKnownTypes { AnyField = Any.Pack(nestedMessage) };
var json = formatter.Format(message);
// Use the descriptor-based parser just for a change.
Assert.AreEqual(message, parser.Parse(json, TestWellKnownTypes.Descriptor));
}
[Test]
public void DataAfterObject()
{
string json = "{} 10";
Assert.Throws<InvalidJsonException>(() => TestAllTypes.Parser.ParseJson(json));
}
/// <summary>
/// JSON equivalent to <see cref="CodedInputStreamTest.MaliciousRecursion"/>
/// </summary>
[Test]
public void MaliciousRecursion()
{
string data64 = CodedInputStreamTest.MakeRecursiveMessage(64).ToString();
string data65 = CodedInputStreamTest.MakeRecursiveMessage(65).ToString();
var parser64 = new JsonParser(new JsonParser.Settings(64));
CodedInputStreamTest.AssertMessageDepth(parser64.Parse<TestRecursiveMessage>(data64), 64);
Assert.Throws<InvalidProtocolBufferException>(() => parser64.Parse<TestRecursiveMessage>(data65));
var parser63 = new JsonParser(new JsonParser.Settings(63));
Assert.Throws<InvalidProtocolBufferException>(() => parser63.Parse<TestRecursiveMessage>(data64));
}
[Test]
[TestCase("AQI")]
[TestCase("_-==")]
public void Bytes_InvalidBase64(string badBase64)
{
string json = "{ \"singleBytes\": \"" + badBase64 + "\" }";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
[TestCase("\"FOREIGN_BAR\"", ForeignEnum.ForeignBar)]
[TestCase("5", ForeignEnum.ForeignBar)]
[TestCase("100", (ForeignEnum)100)]
public void EnumValid(string value, ForeignEnum expectedValue)
{
string json = "{ \"singleForeignEnum\": " + value + " }";
var parsed = TestAllTypes.Parser.ParseJson(json);
Assert.AreEqual(new TestAllTypes { SingleForeignEnum = expectedValue }, parsed);
}
[Test]
[TestCase("\"NOT_A_VALID_VALUE\"")]
[TestCase("5.5")]
public void Enum_Invalid(string value)
{
string json = "{ \"singleForeignEnum\": " + value + " }";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
[Test]
public void OneofDuplicate_Invalid()
{
string json = "{ \"oneofString\": \"x\", \"oneofUint32\": 10 }";
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
}
/// <summary>
/// Various tests use strings which have quotes round them for parsing or as the result
/// of formatting, but without those quotes being specified in the tests (for the sake of readability).
/// This method simply returns the input, wrapped in double quotes.
/// </summary>
internal static string WrapInQuotes(string text)
{
return '"' + text + '"';
}
}
}

View file

@ -0,0 +1,408 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 NUnit.Framework;
using System;
using System.IO;
namespace Google.Protobuf
{
public class JsonTokenizerTest
{
[Test]
public void EmptyObjectValue()
{
AssertTokens("{}", JsonToken.StartObject, JsonToken.EndObject);
}
[Test]
public void EmptyArrayValue()
{
AssertTokens("[]", JsonToken.StartArray, JsonToken.EndArray);
}
[Test]
[TestCase("foo", "foo")]
[TestCase("tab\\t", "tab\t")]
[TestCase("line\\nfeed", "line\nfeed")]
[TestCase("carriage\\rreturn", "carriage\rreturn")]
[TestCase("back\\bspace", "back\bspace")]
[TestCase("form\\ffeed", "form\ffeed")]
[TestCase("escaped\\/slash", "escaped/slash")]
[TestCase("escaped\\\\backslash", "escaped\\backslash")]
[TestCase("escaped\\\"quote", "escaped\"quote")]
[TestCase("foo {}[] bar", "foo {}[] bar")]
[TestCase("foo\\u09aFbar", "foo\u09afbar")] // Digits, upper hex, lower hex
[TestCase("ab\ud800\udc00cd", "ab\ud800\udc00cd")]
[TestCase("ab\\ud800\\udc00cd", "ab\ud800\udc00cd")]
public void StringValue(string json, string expectedValue)
{
AssertTokensNoReplacement("\"" + json + "\"", JsonToken.Value(expectedValue));
}
// Valid surrogate pairs, with mixed escaping. These test cases can't be expressed
// using TestCase as they have no valid UTF-8 representation.
// It's unclear exactly how we should handle a mixture of escaped or not: that can't
// come from UTF-8 text, but could come from a .NET string. For the moment,
// treat it as valid in the obvious way.
[Test]
public void MixedSurrogatePairs()
{
string expected = "\ud800\udc00";
AssertTokens("'\\ud800\udc00'", JsonToken.Value(expected));
AssertTokens("'\ud800\\udc00'", JsonToken.Value(expected));
}
[Test]
public void ObjectDepth()
{
string json = "{ \"foo\": { \"x\": 1, \"y\": [ 0 ] } }";
var tokenizer = JsonTokenizer.FromTextReader(new StringReader(json));
// If we had more tests like this, I'd introduce a helper method... but for one test, it's not worth it.
Assert.AreEqual(0, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.StartObject, tokenizer.Next());
Assert.AreEqual(1, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.Name("foo"), tokenizer.Next());
Assert.AreEqual(1, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.StartObject, tokenizer.Next());
Assert.AreEqual(2, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.Name("x"), tokenizer.Next());
Assert.AreEqual(2, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.Value(1), tokenizer.Next());
Assert.AreEqual(2, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.Name("y"), tokenizer.Next());
Assert.AreEqual(2, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.StartArray, tokenizer.Next());
Assert.AreEqual(2, tokenizer.ObjectDepth); // Depth hasn't changed in array
Assert.AreEqual(JsonToken.Value(0), tokenizer.Next());
Assert.AreEqual(2, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.EndArray, tokenizer.Next());
Assert.AreEqual(2, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.EndObject, tokenizer.Next());
Assert.AreEqual(1, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.EndObject, tokenizer.Next());
Assert.AreEqual(0, tokenizer.ObjectDepth);
Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
Assert.AreEqual(0, tokenizer.ObjectDepth);
}
[Test]
public void ObjectDepth_WithPushBack()
{
string json = "{}";
var tokenizer = JsonTokenizer.FromTextReader(new StringReader(json));
Assert.AreEqual(0, tokenizer.ObjectDepth);
var token = tokenizer.Next();
Assert.AreEqual(1, tokenizer.ObjectDepth);
// When we push back a "start object", we should effectively be back to the previous depth.
tokenizer.PushBack(token);
Assert.AreEqual(0, tokenizer.ObjectDepth);
// Read the same token again, and get back to depth 1
token = tokenizer.Next();
Assert.AreEqual(1, tokenizer.ObjectDepth);
// Now the same in reverse, with EndObject
token = tokenizer.Next();
Assert.AreEqual(0, tokenizer.ObjectDepth);
tokenizer.PushBack(token);
Assert.AreEqual(1, tokenizer.ObjectDepth);
tokenizer.Next();
Assert.AreEqual(0, tokenizer.ObjectDepth);
}
[Test]
[TestCase("embedded tab\t")]
[TestCase("embedded CR\r")]
[TestCase("embedded LF\n")]
[TestCase("embedded bell\u0007")]
[TestCase("bad escape\\a")]
[TestCase("incomplete escape\\")]
[TestCase("incomplete Unicode escape\\u000")]
[TestCase("invalid Unicode escape\\u000H")]
// Surrogate pair handling, both in raw .NET strings and escaped. We only need
// to detect this in strings, as non-ASCII characters anywhere other than in strings
// will already lead to parsing errors.
[TestCase("\\ud800")]
[TestCase("\\udc00")]
[TestCase("\\ud800x")]
[TestCase("\\udc00x")]
[TestCase("\\udc00\\ud800y")]
public void InvalidStringValue(string json)
{
AssertThrowsAfter("\"" + json + "\"");
}
// Tests for invalid strings that can't be expressed in attributes,
// as the constants can't be expressed as UTF-8 strings.
[Test]
public void InvalidSurrogatePairs()
{
AssertThrowsAfter("\"\ud800x\"");
AssertThrowsAfter("\"\udc00y\"");
AssertThrowsAfter("\"\udc00\ud800y\"");
}
[Test]
[TestCase("0", 0)]
[TestCase("-0", 0)] // We don't distinguish between positive and negative 0
[TestCase("1", 1)]
[TestCase("-1", -1)]
// From here on, assume leading sign is okay...
[TestCase("1.125", 1.125)]
[TestCase("1.0", 1)]
[TestCase("1e5", 100000)]
[TestCase("1e000000", 1)] // Weird, but not prohibited by the spec
[TestCase("1E5", 100000)]
[TestCase("1e+5", 100000)]
[TestCase("1E-5", 0.00001)]
[TestCase("123E-2", 1.23)]
[TestCase("123.45E3", 123450)]
[TestCase(" 1 ", 1)]
public void NumberValue(string json, double expectedValue)
{
AssertTokens(json, JsonToken.Value(expectedValue));
}
[Test]
[TestCase("00")]
[TestCase(".5")]
[TestCase("1.")]
[TestCase("1e")]
[TestCase("1e-")]
[TestCase("--")]
[TestCase("--1")]
[TestCase("-1.7977e308")]
[TestCase("1.7977e308")]
public void InvalidNumberValue(string json)
{
AssertThrowsAfter(json);
}
[Test]
[TestCase("nul")]
[TestCase("nothing")]
[TestCase("truth")]
[TestCase("fALSEhood")]
public void InvalidLiterals(string json)
{
AssertThrowsAfter(json);
}
[Test]
public void NullValue()
{
AssertTokens("null", JsonToken.Null);
}
[Test]
public void TrueValue()
{
AssertTokens("true", JsonToken.True);
}
[Test]
public void FalseValue()
{
AssertTokens("false", JsonToken.False);
}
[Test]
public void SimpleObject()
{
AssertTokens("{'x': 'y'}",
JsonToken.StartObject, JsonToken.Name("x"), JsonToken.Value("y"), JsonToken.EndObject);
}
[Test]
[TestCase("[10, 20", 3)]
[TestCase("[10,", 2)]
[TestCase("[10:20]", 2)]
[TestCase("[", 1)]
[TestCase("[,", 1)]
[TestCase("{", 1)]
[TestCase("{,", 1)]
[TestCase("{[", 1)]
[TestCase("{{", 1)]
[TestCase("{0", 1)]
[TestCase("{null", 1)]
[TestCase("{false", 1)]
[TestCase("{true", 1)]
[TestCase("}", 0)]
[TestCase("]", 0)]
[TestCase(",", 0)]
[TestCase("'foo' 'bar'", 1)]
[TestCase(":", 0)]
[TestCase("'foo", 0)] // Incomplete string
[TestCase("{ 'foo' }", 2)]
[TestCase("{ x:1", 1)] // Property names must be quoted
[TestCase("{]", 1)]
[TestCase("[}", 1)]
[TestCase("[1,", 2)]
[TestCase("{'x':0]", 3)]
[TestCase("{ 'foo': }", 2)]
[TestCase("{ 'foo':'bar', }", 3)]
public void InvalidStructure(string json, int expectedValidTokens)
{
// Note: we don't test that the earlier tokens are exactly as expected,
// partly because that's hard to parameterize.
var reader = new StringReader(json.Replace('\'', '"'));
var tokenizer = JsonTokenizer.FromTextReader(reader);
for (int i = 0; i < expectedValidTokens; i++)
{
Assert.IsNotNull(tokenizer.Next());
}
Assert.Throws<InvalidJsonException>(() => tokenizer.Next());
}
[Test]
public void ArrayMixedType()
{
AssertTokens("[1, 'foo', null, false, true, [2], {'x':'y' }]",
JsonToken.StartArray,
JsonToken.Value(1),
JsonToken.Value("foo"),
JsonToken.Null,
JsonToken.False,
JsonToken.True,
JsonToken.StartArray,
JsonToken.Value(2),
JsonToken.EndArray,
JsonToken.StartObject,
JsonToken.Name("x"),
JsonToken.Value("y"),
JsonToken.EndObject,
JsonToken.EndArray);
}
[Test]
public void ObjectMixedType()
{
AssertTokens(@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true,
'f': [2], 'g': {'x':'y' }}",
JsonToken.StartObject,
JsonToken.Name("a"),
JsonToken.Value(1),
JsonToken.Name("b"),
JsonToken.Value("bar"),
JsonToken.Name("c"),
JsonToken.Null,
JsonToken.Name("d"),
JsonToken.False,
JsonToken.Name("e"),
JsonToken.True,
JsonToken.Name("f"),
JsonToken.StartArray,
JsonToken.Value(2),
JsonToken.EndArray,
JsonToken.Name("g"),
JsonToken.StartObject,
JsonToken.Name("x"),
JsonToken.Value("y"),
JsonToken.EndObject,
JsonToken.EndObject);
}
[Test]
public void NextAfterEndDocumentThrows()
{
var tokenizer = JsonTokenizer.FromTextReader(new StringReader("null"));
Assert.AreEqual(JsonToken.Null, tokenizer.Next());
Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
Assert.Throws<InvalidOperationException>(() => tokenizer.Next());
}
[Test]
public void CanPushBackEndDocument()
{
var tokenizer = JsonTokenizer.FromTextReader(new StringReader("null"));
Assert.AreEqual(JsonToken.Null, tokenizer.Next());
Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
tokenizer.PushBack(JsonToken.EndDocument);
Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
Assert.Throws<InvalidOperationException>(() => tokenizer.Next());
}
/// <summary>
/// Asserts that the specified JSON is tokenized into the given sequence of tokens.
/// All apostrophes are first converted to double quotes, allowing any tests
/// that don't need to check actual apostrophe handling to use apostrophes in the JSON, avoiding
/// messy string literal escaping. The "end document" token is not specified in the list of
/// expected tokens, but is implicit.
/// </summary>
private static void AssertTokens(string json, params JsonToken[] expectedTokens)
{
AssertTokensNoReplacement(json.Replace('\'', '"'), expectedTokens);
}
/// <summary>
/// Asserts that the specified JSON is tokenized into the given sequence of tokens.
/// Unlike <see cref="AssertTokens(string, JsonToken[])"/>, this does not perform any character
/// replacement on the specified JSON, and should be used when the text contains apostrophes which
/// are expected to be used *as* apostrophes. The "end document" token is not specified in the list of
/// expected tokens, but is implicit.
/// </summary>
private static void AssertTokensNoReplacement(string json, params JsonToken[] expectedTokens)
{
var reader = new StringReader(json);
var tokenizer = JsonTokenizer.FromTextReader(reader);
for (int i = 0; i < expectedTokens.Length; i++)
{
var actualToken = tokenizer.Next();
if (actualToken == JsonToken.EndDocument)
{
Assert.Fail("Expected {0} but reached end of token stream", expectedTokens[i]);
}
Assert.AreEqual(expectedTokens[i], actualToken);
}
var finalToken = tokenizer.Next();
if (finalToken != JsonToken.EndDocument)
{
Assert.Fail("Expected token stream to be exhausted; received {0}", finalToken);
}
}
private static void AssertThrowsAfter(string json, params JsonToken[] expectedTokens)
{
var reader = new StringReader(json);
var tokenizer = JsonTokenizer.FromTextReader(reader);
for (int i = 0; i < expectedTokens.Length; i++)
{
var actualToken = tokenizer.Next();
if (actualToken == JsonToken.EndDocument)
{
Assert.Fail("Expected {0} but reached end of document", expectedTokens[i]);
}
Assert.AreEqual(expectedTokens[i], actualToken);
}
Assert.Throws<InvalidJsonException>(() => tokenizer.Next());
}
}
}

View file

@ -0,0 +1,259 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 System.Linq;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using UnitTest.Issues.TestProtos;
namespace Google.Protobuf.Reflection
{
/// <summary>
/// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
/// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
/// </summary>
public class DescriptorsTest
{
[Test]
public void FileDescriptor()
{
FileDescriptor file = UnittestProto3Reflection.Descriptor;
Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Name);
Assert.AreEqual("protobuf_unittest", file.Package);
Assert.AreEqual("UnittestProto", file.Proto.Options.JavaOuterClassname);
Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Proto.Name);
// unittest.proto doesn't have any public imports, but unittest_import.proto does.
Assert.AreEqual(0, file.PublicDependencies.Count);
Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.PublicDependencies.Count);
Assert.AreEqual(UnittestImportPublicProto3Reflection.Descriptor, UnittestImportProto3Reflection.Descriptor.PublicDependencies[0]);
Assert.AreEqual(1, file.Dependencies.Count);
Assert.AreEqual(UnittestImportProto3Reflection.Descriptor, file.Dependencies[0]);
MessageDescriptor messageType = TestAllTypes.Descriptor;
Assert.AreSame(typeof(TestAllTypes), messageType.ClrType);
Assert.AreSame(TestAllTypes.Parser, messageType.Parser);
Assert.AreEqual(messageType, file.MessageTypes[0]);
Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
Assert.Null(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
Assert.Null(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes"));
for (int i = 0; i < file.MessageTypes.Count; i++)
{
Assert.AreEqual(i, file.MessageTypes[i].Index);
}
Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
Assert.Null(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
Assert.Null(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum"));
Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.EnumTypes.Count);
Assert.AreEqual("ImportEnum", UnittestImportProto3Reflection.Descriptor.EnumTypes[0].Name);
for (int i = 0; i < file.EnumTypes.Count; i++)
{
Assert.AreEqual(i, file.EnumTypes[i].Index);
}
Assert.AreEqual(10, file.SerializedData[0]);
}
[Test]
public void MessageDescriptor()
{
MessageDescriptor messageType = TestAllTypes.Descriptor;
MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor;
Assert.AreEqual("TestAllTypes", messageType.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
Assert.AreEqual(UnittestProto3Reflection.Descriptor, messageType.File);
Assert.IsNull(messageType.ContainingType);
Assert.IsNull(messageType.Proto.Options);
Assert.AreEqual("TestAllTypes", messageType.Name);
Assert.AreEqual("NestedMessage", nestedType.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Assert.AreEqual(messageType, nestedType.ContainingType);
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));
var fieldsInDeclarationOrder = messageType.Fields.InDeclarationOrder();
for (int i = 0; i < fieldsInDeclarationOrder.Count; i++)
{
Assert.AreEqual(i, fieldsInDeclarationOrder[i].Index);
}
Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage"));
Assert.Null(messageType.FindDescriptor<MessageDescriptor>("NoSuchType"));
for (int i = 0; i < messageType.NestedTypes.Count; i++)
{
Assert.AreEqual(i, messageType.NestedTypes[i].Index);
}
Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum"));
Assert.Null(messageType.FindDescriptor<EnumDescriptor>("NoSuchType"));
for (int i = 0; i < messageType.EnumTypes.Count; i++)
{
Assert.AreEqual(i, messageType.EnumTypes[i].Index);
}
}
[Test]
public void FieldDescriptor()
{
MessageDescriptor messageType = TestAllTypes.Descriptor;
FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("single_int32");
FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("single_nested_enum");
FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("single_foreign_message");
Assert.AreEqual("single_int32", primitiveField.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes.single_int32",
primitiveField.FullName);
Assert.AreEqual(1, primitiveField.FieldNumber);
Assert.AreEqual(messageType, primitiveField.ContainingType);
Assert.AreEqual(UnittestProto3Reflection.Descriptor, primitiveField.File);
Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
Assert.IsNull(primitiveField.Proto.Options);
Assert.AreEqual("single_nested_enum", enumField.Name);
Assert.AreEqual(FieldType.Enum, enumField.FieldType);
// Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType);
Assert.AreEqual("single_foreign_message", messageField.Name);
Assert.AreEqual(FieldType.Message, messageField.FieldType);
Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType);
}
[Test]
public void FieldDescriptorLabel()
{
FieldDescriptor singleField =
TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("single_int32");
FieldDescriptor repeatedField =
TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
Assert.IsFalse(singleField.IsRepeated);
Assert.IsTrue(repeatedField.IsRepeated);
}
[Test]
public void EnumDescriptor()
{
// Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
EnumDescriptor enumType = UnittestProto3Reflection.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
Assert.AreEqual("ForeignEnum", enumType.Name);
Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName);
Assert.AreEqual(UnittestProto3Reflection.Descriptor, enumType.File);
Assert.Null(enumType.ContainingType);
Assert.Null(enumType.Proto.Options);
Assert.AreEqual("NestedEnum", nestedType.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum",
nestedType.FullName);
Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
Assert.AreEqual(value, enumType.Values[1]);
Assert.AreEqual("FOREIGN_FOO", value.Name);
Assert.AreEqual(4, value.Number);
Assert.AreEqual((int) ForeignEnum.ForeignFoo, value.Number);
Assert.AreEqual(value, enumType.FindValueByNumber(4));
Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE"));
for (int i = 0; i < enumType.Values.Count; i++)
{
Assert.AreEqual(i, enumType.Values[i].Index);
}
}
[Test]
public void OneofDescriptor()
{
OneofDescriptor descriptor = TestAllTypes.Descriptor.FindDescriptor<OneofDescriptor>("oneof_field");
Assert.AreEqual("oneof_field", descriptor.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes.oneof_field", descriptor.FullName);
var expectedFields = new[] {
TestAllTypes.OneofBytesFieldNumber,
TestAllTypes.OneofNestedMessageFieldNumber,
TestAllTypes.OneofStringFieldNumber,
TestAllTypes.OneofUint32FieldNumber }
.Select(fieldNumber => TestAllTypes.Descriptor.FindFieldByNumber(fieldNumber))
.ToList();
foreach (var field in expectedFields)
{
Assert.AreSame(descriptor, field.ContainingOneof);
}
CollectionAssert.AreEquivalent(expectedFields, descriptor.Fields);
}
[Test]
public void MapEntryMessageDescriptor()
{
var descriptor = MapWellKnownTypes.Descriptor.NestedTypes[0];
Assert.IsNull(descriptor.Parser);
Assert.IsNull(descriptor.ClrType);
Assert.IsNull(descriptor.Fields[1].Accessor);
}
// From TestFieldOrdering:
// string my_string = 11;
// int64 my_int = 1;
// float my_float = 101;
// NestedMessage single_nested_message = 200;
[Test]
public void FieldListOrderings()
{
var fields = TestFieldOrderings.Descriptor.Fields;
Assert.AreEqual(new[] { 11, 1, 101, 200 }, fields.InDeclarationOrder().Select(x => x.FieldNumber));
Assert.AreEqual(new[] { 1, 11, 101, 200 }, fields.InFieldNumberOrder().Select(x => x.FieldNumber));
}
[Test]
public void DescriptorProtoFileDescriptor()
{
var descriptor = Google.Protobuf.Reflection.FileDescriptor.DescriptorProtoFileDescriptor;
Assert.AreEqual("google/protobuf/descriptor.proto", descriptor.Name);
}
}
}

View file

@ -0,0 +1,218 @@
#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.ForeignFoo);
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.ForeignFoo,
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());
}
}
}

View file

@ -0,0 +1,94 @@
#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 Google.Protobuf.WellKnownTypes;
using NUnit.Framework;
namespace Google.Protobuf.Reflection
{
public class TypeRegistryTest
{
// Most of our tests use messages. Simple test that we really can use files...
[Test]
public void CreateWithFileDescriptor()
{
var registry = TypeRegistry.FromFiles(DurationReflection.Descriptor, StructReflection.Descriptor);
AssertDescriptorPresent(registry, Duration.Descriptor);
AssertDescriptorPresent(registry, ListValue.Descriptor);
AssertDescriptorAbsent(registry, Timestamp.Descriptor);
}
[Test]
public void TypesFromSameFile()
{
// Just for kicks, let's start with a nested type
var registry = TypeRegistry.FromMessages(TestAllTypes.Types.NestedMessage.Descriptor);
// Top-level...
AssertDescriptorPresent(registry, TestFieldOrderings.Descriptor);
// ... and nested (not the same as the original NestedMessage!)
AssertDescriptorPresent(registry, TestFieldOrderings.Types.NestedMessage.Descriptor);
}
[Test]
public void DependenciesAreIncluded()
{
var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
// Direct dependencies
AssertDescriptorPresent(registry, ImportMessage.Descriptor);
// Public dependencies
AssertDescriptorPresent(registry, PublicImportMessage.Descriptor);
}
[Test]
public void DuplicateFiles()
{
// Duplicates via dependencies and simply via repetition
var registry = TypeRegistry.FromFiles(
UnittestProto3Reflection.Descriptor, UnittestImportProto3Reflection.Descriptor,
TimestampReflection.Descriptor, TimestampReflection.Descriptor);
AssertDescriptorPresent(registry, TestAllTypes.Descriptor);
AssertDescriptorPresent(registry, ImportMessage.Descriptor);
AssertDescriptorPresent(registry, Timestamp.Descriptor);
}
private static void AssertDescriptorPresent(TypeRegistry registry, MessageDescriptor descriptor)
{
Assert.AreSame(descriptor, registry.Find(descriptor.FullName));
}
private static void AssertDescriptorAbsent(TypeRegistry registry, MessageDescriptor descriptor)
{
Assert.IsNull(registry.Find(descriptor.FullName));
}
}
}

View file

@ -0,0 +1,42 @@
#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
namespace Google.Protobuf
{
// Just a sample enum with positive and negative values to be used in tests.
internal enum SampleEnum
{
NegativeValue = -2,
None = 0,
PositiveValue = 3
}
}

View file

@ -0,0 +1,99 @@
#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 System;
using Google.Protobuf.TestProtos;
namespace Google.Protobuf
{
/// <summary>
/// Helper methods to create sample instances of types generated from unit test messages.
/// </summary>
public class SampleMessages
{
/// <summary>
/// Creates a new sample TestAllTypes message with all fields populated.
/// The "oneof" field is populated with the string property (OneofString).
/// </summary>
public static TestAllTypes CreateFullTestAllTypes()
{
return new TestAllTypes
{
SingleBool = true,
SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
SingleDouble = 23.5,
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
SingleSint64 = -12345678901235,
SingleString = "test",
SingleUint32 = UInt32.MaxValue,
SingleUint64 = UInt64.MaxValue,
RepeatedBool = { true, false },
RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6), ByteString.CopyFrom(new byte[1000]) },
RepeatedDouble = { -12.25, 23.5 },
RepeatedFixed32 = { UInt32.MaxValue, 23 },
RepeatedFixed64 = { UInt64.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, Int64.MaxValue },
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
RepeatedSint64 = { -12345678901235, 123 },
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
OneofString = "Oneof string"
};
}
}
}

View file

@ -0,0 +1,62 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 UnitTest.Issues.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
{
public class TestCornerCases
{
[Test]
public void TestRoundTripNegativeEnums()
{
NegativeEnumMessage msg = new NegativeEnumMessage
{
Value = NegativeEnum.MinusOne,
Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
};
Assert.AreEqual(58, msg.CalculateSize());
byte[] bytes = new byte[58];
CodedOutputStream output = new CodedOutputStream(bytes);
msg.WriteTo(output);
Assert.AreEqual(0, output.SpaceLeft);
NegativeEnumMessage copy = NegativeEnumMessage.Parser.ParseFrom(bytes);
Assert.AreEqual(msg, copy);
}
}
}

View file

@ -0,0 +1,45 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2016 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
namespace Google.Protobuf.TestProtos
{
/// <summary>
/// A message with custom diagnostics (to test that they work).
/// </summary>
public partial class ForeignMessage : ICustomDiagnosticMessage
{
public string ToDiagnosticString()
{
return $"{{ \"c\": {C}, \"@cInHex\": \"{C:x}\" }}";
}
}
}

View file

@ -0,0 +1,116 @@
#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;
namespace Google.Protobuf.WellKnownTypes
{
public class AnyTest
{
[Test]
public void Pack()
{
var message = SampleMessages.CreateFullTestAllTypes();
var any = Any.Pack(message);
Assert.AreEqual("type.googleapis.com/protobuf_unittest.TestAllTypes", any.TypeUrl);
Assert.AreEqual(message.CalculateSize(), any.Value.Length);
}
[Test]
public void Pack_WithCustomPrefix()
{
var message = SampleMessages.CreateFullTestAllTypes();
var any = Any.Pack(message, "foo.bar/baz");
Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
Assert.AreEqual(message.CalculateSize(), any.Value.Length);
}
[Test]
public void Pack_WithCustomPrefixTrailingSlash()
{
var message = SampleMessages.CreateFullTestAllTypes();
var any = Any.Pack(message, "foo.bar/baz/");
Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
Assert.AreEqual(message.CalculateSize(), any.Value.Length);
}
[Test]
public void Unpack_WrongType()
{
var message = SampleMessages.CreateFullTestAllTypes();
var any = Any.Pack(message);
Assert.Throws<InvalidProtocolBufferException>(() => any.Unpack<TestOneof>());
}
[Test]
public void Unpack_Success()
{
var message = SampleMessages.CreateFullTestAllTypes();
var any = Any.Pack(message);
var unpacked = any.Unpack<TestAllTypes>();
Assert.AreEqual(message, unpacked);
}
[Test]
public void Unpack_CustomPrefix_Success()
{
var message = SampleMessages.CreateFullTestAllTypes();
var any = Any.Pack(message, "foo.bar/baz");
var unpacked = any.Unpack<TestAllTypes>();
Assert.AreEqual(message, unpacked);
}
[Test]
public void ToString_WithValues()
{
var message = SampleMessages.CreateFullTestAllTypes();
var any = Any.Pack(message);
var text = any.ToString();
Assert.That(text, Does.Contain("\"@value\": \"" + message.ToByteString().ToBase64() + "\""));
}
[Test]
public void ToString_Empty()
{
var any = new Any();
Assert.AreEqual("{ \"@type\": \"\", \"@value\": \"\" }", any.ToString());
}
[Test]
public void ToString_MessageContainingAny()
{
var message = new TestWellKnownTypes { AnyField = new Any() };
Assert.AreEqual("{ \"anyField\": { \"@type\": \"\", \"@value\": \"\" } }", message.ToString());
}
}
}

View file

@ -0,0 +1,132 @@
#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 NUnit.Framework;
using System;
namespace Google.Protobuf.WellKnownTypes
{
public class DurationTest
{
[Test]
public void ToTimeSpan()
{
Assert.AreEqual(TimeSpan.FromSeconds(1), new Duration { Seconds = 1 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromSeconds(-1), new Duration { Seconds = -1 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromMilliseconds(1), new Duration { Nanos = 1000000 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromMilliseconds(-1), new Duration { Nanos = -1000000 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(1), new Duration { Nanos = 100 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(-1), new Duration { Nanos = -100 }.ToTimeSpan());
// Rounding is towards 0
Assert.AreEqual(TimeSpan.FromTicks(2), new Duration { Nanos = 250 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(-2), new Duration { Nanos = -250 }.ToTimeSpan());
}
[Test]
public void Addition()
{
Assert.AreEqual(new Duration { Seconds = 2, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } + new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Seconds = -2, Nanos = -100000000 },
new Duration { Seconds = -1, Nanos = -600000000 } + new Duration { Nanos = -500000000 });
Assert.AreEqual(new Duration { Seconds = 1, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } + new Duration { Nanos = -500000000 });
// Non-normalized durations, or non-normalized intermediate results
Assert.AreEqual(new Duration { Seconds = 1 },
new Duration { Seconds = 1, Nanos = -500000000 } + new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Nanos = -900000000 },
new Duration { Seconds = -1, Nanos = -100000000 } + new Duration { Nanos = 200000000 });
Assert.AreEqual(new Duration { Nanos = 900000000 },
new Duration { Seconds = 1, Nanos = 100000000 } + new Duration { Nanos = -200000000 });
}
[Test]
public void Subtraction()
{
Assert.AreEqual(new Duration { Seconds = 1, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } - new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Seconds = -1, Nanos = -100000000 },
new Duration { Seconds = -1, Nanos = -600000000 } - new Duration { Nanos = -500000000 });
Assert.AreEqual(new Duration { Seconds = 2, Nanos = 100000000 },
new Duration { Seconds = 1, Nanos = 600000000 } - new Duration { Nanos = -500000000 });
// Non-normalized durations
Assert.AreEqual(new Duration(),
new Duration { Seconds = 1, Nanos = -500000000 } - new Duration { Nanos = 500000000 });
Assert.AreEqual(new Duration { Seconds = 1 },
new Duration { Nanos = 2000000000 } - new Duration { Nanos = 1000000000 });
}
[Test]
public void FromTimeSpan()
{
Assert.AreEqual(new Duration { Seconds = 1 }, Duration.FromTimeSpan(TimeSpan.FromSeconds(1)));
Assert.AreEqual(new Duration { Nanos = Duration.NanosecondsPerTick }, Duration.FromTimeSpan(TimeSpan.FromTicks(1)));
}
[Test]
[TestCase(0, Duration.MaxNanoseconds + 1)]
[TestCase(0, Duration.MinNanoseconds - 1)]
[TestCase(Duration.MinSeconds - 1, 0)]
[TestCase(Duration.MaxSeconds + 1, 0)]
[TestCase(1, -1)]
[TestCase(-1, 1)]
public void ToTimeSpan_Invalid(long seconds, int nanoseconds)
{
var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
Assert.Throws<InvalidOperationException>(() => duration.ToTimeSpan());
}
[Test]
[TestCase(0, Duration.MaxNanoseconds)]
[TestCase(0, Duration.MinNanoseconds)]
[TestCase(Duration.MinSeconds, Duration.MinNanoseconds)]
[TestCase(Duration.MaxSeconds, Duration.MaxNanoseconds)]
public void ToTimeSpan_Valid(long seconds, int nanoseconds)
{
// Only testing that these values don't throw, unlike their similar tests in ToTimeSpan_Invalid
var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
duration.ToTimeSpan();
}
[Test]
public void ToString_NonNormalized()
{
// Just a single example should be sufficient...
var duration = new Duration { Seconds = 1, Nanos = -1 };
Assert.AreEqual("{ \"@warning\": \"Invalid Duration\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
}
}
}

View file

@ -0,0 +1,62 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2016 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 NUnit.Framework;
namespace Google.Protobuf.WellKnownTypes
{
public class FieldMaskTest
{
[Test]
[TestCase("foo__bar")]
[TestCase("foo_3_ar")]
[TestCase("fooBar")]
public void ToString_Invalid(string input)
{
var mask = new FieldMask { Paths = { input } };
var text = mask.ToString();
// More specific test below
Assert.That(text, Does.Contain("@warning"));
Assert.That(text, Does.Contain(input));
}
[Test]
public void ToString_Invalid_Precise()
{
var mask = new FieldMask { Paths = { "x", "foo__bar", @"x\y" } };
Assert.AreEqual(
"{ \"@warning\": \"Invalid FieldMask\", \"paths\": [ \"x\", \"foo__bar\", \"x\\\\y\" ] }",
mask.ToString());
}
}
}

View file

@ -0,0 +1,115 @@
#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 NUnit.Framework;
using System;
namespace Google.Protobuf.WellKnownTypes
{
public class TimestampTest
{
[Test]
public void FromAndToDateTime()
{
DateTime utcMin = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc);
DateTime utcMax = DateTime.SpecifyKind(DateTime.MaxValue, DateTimeKind.Utc);
AssertRoundtrip(new Timestamp { Seconds = -62135596800 }, utcMin);
AssertRoundtrip(new Timestamp { Seconds = 253402300799, Nanos = 999999900 }, utcMax);
AssertRoundtrip(new Timestamp(), new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Nanos = 1000000}, new DateTime(1970, 1, 1, 0, 0, 0, 1, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Seconds = -1, Nanos = 999000000 }, new DateTime(1969, 12, 31, 23, 59, 59, 999, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Seconds = 3600 }, new DateTime(1970, 1, 1, 1, 0, 0, DateTimeKind.Utc));
AssertRoundtrip(new Timestamp { Seconds = -3600 }, new DateTime(1969, 12, 31, 23, 0, 0, DateTimeKind.Utc));
}
[Test]
public void ToDateTimeTruncation()
{
var t1 = new Timestamp { Seconds = 1, Nanos = 1000000 + Duration.NanosecondsPerTick - 1 };
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 1, DateTimeKind.Utc).AddMilliseconds(1), t1.ToDateTime());
var t2 = new Timestamp { Seconds = -1, Nanos = 1000000 + Duration.NanosecondsPerTick - 1 };
Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 59).AddMilliseconds(1), t2.ToDateTime());
}
[Test]
[TestCase(Timestamp.UnixSecondsAtBclMinValue - 1, Timestamp.MaxNanos)]
[TestCase(Timestamp.UnixSecondsAtBclMaxValue + 1, 0)]
[TestCase(0, -1)]
[TestCase(0, Timestamp.MaxNanos + 1)]
public void ToDateTime_OutOfRange(long seconds, int nanoseconds)
{
var value = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
Assert.Throws<InvalidOperationException>(() => value.ToDateTime());
}
// 1ns larger or smaller than the above values
[Test]
[TestCase(Timestamp.UnixSecondsAtBclMinValue, 0)]
[TestCase(Timestamp.UnixSecondsAtBclMaxValue, Timestamp.MaxNanos)]
[TestCase(0, 0)]
[TestCase(0, Timestamp.MaxNanos)]
public void ToDateTime_ValidBoundaries(long seconds, int nanoseconds)
{
var value = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
value.ToDateTime();
}
private static void AssertRoundtrip(Timestamp timestamp, DateTime dateTime)
{
Assert.AreEqual(timestamp, Timestamp.FromDateTime(dateTime));
Assert.AreEqual(dateTime, timestamp.ToDateTime());
Assert.AreEqual(DateTimeKind.Utc, timestamp.ToDateTime().Kind);
}
[Test]
public void Arithmetic()
{
Timestamp t1 = new Timestamp { Seconds = 10000, Nanos = 5000 };
Timestamp t2 = new Timestamp { Seconds = 8000, Nanos = 10000 };
Duration difference = new Duration { Seconds = 1999, Nanos = Duration.NanosecondsPerSecond - 5000 };
Assert.AreEqual(difference, t1 - t2);
Assert.AreEqual(-difference, t2 - t1);
Assert.AreEqual(t1, t2 + difference);
Assert.AreEqual(t2, t1 - difference);
}
[Test]
public void ToString_NonNormalized()
{
// Just a single example should be sufficient...
var duration = new Timestamp { Seconds = 1, Nanos = -1 };
Assert.AreEqual("{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
}
}
}

View file

@ -0,0 +1,421 @@
#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 System;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Collections;
using System.IO;
namespace Google.Protobuf.WellKnownTypes
{
public class WrappersTest
{
[Test]
public void NullIsDefault()
{
var message = new TestWellKnownTypes();
Assert.IsNull(message.StringField);
Assert.IsNull(message.BytesField);
Assert.IsNull(message.BoolField);
Assert.IsNull(message.FloatField);
Assert.IsNull(message.DoubleField);
Assert.IsNull(message.Int32Field);
Assert.IsNull(message.Int64Field);
Assert.IsNull(message.Uint32Field);
Assert.IsNull(message.Uint64Field);
}
[Test]
public void NonDefaultSingleValues()
{
var message = new TestWellKnownTypes
{
StringField = "x",
BytesField = ByteString.CopyFrom(1, 2, 3),
BoolField = true,
FloatField = 12.5f,
DoubleField = 12.25d,
Int32Field = 1,
Int64Field = 2,
Uint32Field = 3,
Uint64Field = 4
};
var bytes = message.ToByteArray();
var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual("x", parsed.StringField);
Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), parsed.BytesField);
Assert.AreEqual(true, parsed.BoolField);
Assert.AreEqual(12.5f, parsed.FloatField);
Assert.AreEqual(12.25d, parsed.DoubleField);
Assert.AreEqual(1, parsed.Int32Field);
Assert.AreEqual(2L, parsed.Int64Field);
Assert.AreEqual(3U, parsed.Uint32Field);
Assert.AreEqual(4UL, parsed.Uint64Field);
}
[Test]
public void NonNullDefaultIsPreservedThroughSerialization()
{
var message = new TestWellKnownTypes
{
StringField = "",
BytesField = ByteString.Empty,
BoolField = false,
FloatField = 0f,
DoubleField = 0d,
Int32Field = 0,
Int64Field = 0,
Uint32Field = 0,
Uint64Field = 0
};
var bytes = message.ToByteArray();
var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual("", parsed.StringField);
Assert.AreEqual(ByteString.Empty, parsed.BytesField);
Assert.AreEqual(false, parsed.BoolField);
Assert.AreEqual(0f, parsed.FloatField);
Assert.AreEqual(0d, parsed.DoubleField);
Assert.AreEqual(0, parsed.Int32Field);
Assert.AreEqual(0L, parsed.Int64Field);
Assert.AreEqual(0U, parsed.Uint32Field);
Assert.AreEqual(0UL, parsed.Uint64Field);
}
[Test]
public void RepeatedWrappersProhibitNullItems()
{
var message = new RepeatedWellKnownTypes();
Assert.Throws<ArgumentNullException>(() => message.BoolField.Add((bool?) null));
Assert.Throws<ArgumentNullException>(() => message.Int32Field.Add((int?) null));
Assert.Throws<ArgumentNullException>(() => message.StringField.Add((string) null));
Assert.Throws<ArgumentNullException>(() => message.BytesField.Add((ByteString) null));
}
[Test]
public void RepeatedWrappersSerializeDeserialize()
{
var message = new RepeatedWellKnownTypes
{
BoolField = { true, false },
BytesField = { ByteString.CopyFrom(1, 2, 3), ByteString.CopyFrom(4, 5, 6), ByteString.Empty },
DoubleField = { 12.5, -1.5, 0d },
FloatField = { 123.25f, -20f, 0f },
Int32Field = { int.MaxValue, int.MinValue, 0 },
Int64Field = { long.MaxValue, long.MinValue, 0L },
StringField = { "First", "Second", "" },
Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
};
var bytes = message.ToByteArray();
var parsed = RepeatedWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
// Just to test a single value for sanity...
Assert.AreEqual("Second", message.StringField[1]);
}
[Test]
public void RepeatedWrappersBinaryFormat()
{
// At one point we accidentally used a packed format for repeated wrappers, which is wrong (and weird).
// This test is just to prove that we use the right format.
var rawOutput = new MemoryStream();
var output = new CodedOutputStream(rawOutput);
// Write a value of 5
output.WriteTag(RepeatedWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(2);
output.WriteTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint);
output.WriteInt32(5);
// Write a value of 0 (empty message)
output.WriteTag(RepeatedWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
output.WriteLength(0);
output.Flush();
var expectedBytes = rawOutput.ToArray();
var message = new RepeatedWellKnownTypes { Int32Field = { 5, 0 } };
var actualBytes = message.ToByteArray();
Assert.AreEqual(expectedBytes, actualBytes);
}
[Test]
public void MapWrappersSerializeDeserialize()
{
// Note: no null values here, as they are prohibited in map fields
// (despite being representable).
var message = new MapWellKnownTypes
{
BoolField = { { 10, false }, { 20, true } },
BytesField = {
{ -1, ByteString.CopyFrom(1, 2, 3) },
{ 10, ByteString.CopyFrom(4, 5, 6) },
{ 1000, ByteString.Empty },
},
DoubleField = { { 1, 12.5 }, { 10, -1.5 }, { 20, 0d } },
FloatField = { { 2, 123.25f }, { 3, -20f }, { 4, 0f } },
Int32Field = { { 5, int.MaxValue }, { 6, int.MinValue }, { 7, 0 } },
Int64Field = { { 8, long.MaxValue }, { 9, long.MinValue }, { 10, 0L } },
StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" } },
Uint32Field = { { 15, uint.MaxValue }, { 16, uint.MinValue }, { 17, 0U } },
Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } },
};
var bytes = message.ToByteArray();
var parsed = MapWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
// Just to test a single value for sanity...
Assert.AreEqual("Second", message.StringField[12]);
}
[Test]
public void Reflection_SingleValues()
{
var message = new TestWellKnownTypes
{
StringField = "x",
BytesField = ByteString.CopyFrom(1, 2, 3),
BoolField = true,
FloatField = 12.5f,
DoubleField = 12.25d,
Int32Field = 1,
Int64Field = 2,
Uint32Field = 3,
Uint64Field = 4
};
var fields = TestWellKnownTypes.Descriptor.Fields;
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(4UL, fields[TestWellKnownTypes.Uint64FieldFieldNumber].Accessor.GetValue(message));
// And a couple of null fields...
message.StringField = null;
message.FloatField = null;
Assert.IsNull(fields[TestWellKnownTypes.StringFieldFieldNumber].Accessor.GetValue(message));
Assert.IsNull(fields[TestWellKnownTypes.FloatFieldFieldNumber].Accessor.GetValue(message));
}
[Test]
public void Reflection_RepeatedFields()
{
// 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.Fields;
var list = (IList) fields[RepeatedWellKnownTypes.Int32FieldFieldNumber].Accessor.GetValue(message);
CollectionAssert.AreEqual(new[] { 1, 2 }, list);
}
[Test]
public void Reflection_MapFields()
{
// Just a single example... note that we can't have a null value here despite the value type being int?
var message = new MapWellKnownTypes { Int32Field = { { 1, 2 } } };
var fields = MapWellKnownTypes.Descriptor.Fields;
var dictionary = (IDictionary) fields[MapWellKnownTypes.Int32FieldFieldNumber].Accessor.GetValue(message);
Assert.AreEqual(2, dictionary[1]);
}
[Test]
public void Oneof()
{
var message = new OneofWellKnownTypes { EmptyField = new Empty() };
// Start off with a non-wrapper
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.EmptyField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.StringField = "foo";
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.StringField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.StringField = "foo";
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.StringField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.DoubleField = 0.0f;
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.DoubleField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.DoubleField = 1.0f;
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.DoubleField, message.OneofFieldCase);
AssertOneofRoundTrip(message);
message.ClearOneofField();
Assert.AreEqual(OneofWellKnownTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
AssertOneofRoundTrip(message);
}
private void AssertOneofRoundTrip(OneofWellKnownTypes message)
{
// Normal roundtrip, but explicitly checking the case...
var bytes = message.ToByteArray();
var parsed = OneofWellKnownTypes.Parser.ParseFrom(bytes);
Assert.AreEqual(message, parsed);
Assert.AreEqual(message.OneofFieldCase, parsed.OneofFieldCase);
}
[Test]
[TestCase("x", "y", "y")]
[TestCase("x", "", "x")]
[TestCase("x", null, "x")]
[TestCase("", "y", "y")]
[TestCase("", "", "")]
[TestCase("", null, "")]
[TestCase(null, "y", "y")]
[TestCase(null, "", "")]
[TestCase(null, null, null)]
public void Merging(string original, string merged, string expected)
{
var originalMessage = new TestWellKnownTypes { StringField = original };
var mergingMessage = new TestWellKnownTypes { StringField = merged };
originalMessage.MergeFrom(mergingMessage);
Assert.AreEqual(expected, originalMessage.StringField);
// Try it using MergeFrom(CodedInputStream) too...
originalMessage = new TestWellKnownTypes { StringField = original };
originalMessage.MergeFrom(mergingMessage.ToByteArray());
Assert.AreEqual(expected, originalMessage.StringField);
}
// Merging is odd with wrapper types, due to the way that default values aren't emitted in
// the binary stream. In fact we cheat a little bit - a message with an explicitly present default
// value will have that default value ignored. See issue 615. Fixing this would require significant upheaval to
// the FieldCodec side of things.
[Test]
public void MergingStreamExplicitValue()
{
var message = new TestWellKnownTypes { Int32Field = 5 };
// Create a byte array which has the data of an Int32Value explicitly containing a value of 0.
// This wouldn't normally happen.
byte[] bytes;
var wrapperTag = WireFormat.MakeTag(TestWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
var valueTag = WireFormat.MakeTag(Int32Value.ValueFieldNumber, WireFormat.WireType.Varint);
using (var stream = new MemoryStream())
{
var coded = new CodedOutputStream(stream);
coded.WriteTag(wrapperTag);
coded.WriteLength(2); // valueTag + a value 0, each one byte
coded.WriteTag(valueTag);
coded.WriteInt32(0);
coded.Flush();
bytes = stream.ToArray();
}
message.MergeFrom(bytes);
// A normal implementation would have 0 now, as the explicit default would have been overwritten the 5.
// With the FieldCodec for Nullable<int>, we can't tell the difference between an implicit 0 and an explicit 0.
Assert.AreEqual(5, message.Int32Field);
}
[Test]
public void MergingStreamNoValue()
{
var message = new TestWellKnownTypes { Int32Field = 5 };
// Create a byte array which an Int32 field, but with no value.
var bytes = new TestWellKnownTypes { Int32Field = 0 }.ToByteArray();
Assert.AreEqual(2, bytes.Length); // The tag for Int32Field is a single byte, then a byte indicating a 0-length message.
message.MergeFrom(bytes);
// The "implicit" 0 did *not* overwrite the value.
// (This is the correct behaviour.)
Assert.AreEqual(5, message.Int32Field);
}
// All permutations of origin/merging value being null, zero (default) or non-default.
// As this is the in-memory version, we don't need to worry about the difference between implicit and explicit 0.
[Test]
[TestCase(null, null, null)]
[TestCase(null, 0, 0)]
[TestCase(null, 5, 5)]
[TestCase(0, null, 0)]
[TestCase(0, 0, 0)]
[TestCase(0, 5, 5)]
[TestCase(5, null, 5)]
[TestCase(5, 0, 5)]
[TestCase(5, 10, 10)]
public void MergingMessageWithZero(int? originValue, int? mergingValue, int? expectedResult)
{
// This differs from the MergingStreamCornerCase because when we merge message *objects*,
// we ignore default values from the "source".
var message1 = new TestWellKnownTypes { Int32Field = originValue };
var message2 = new TestWellKnownTypes { Int32Field = mergingValue };
message1.MergeFrom(message2);
Assert.AreEqual(expectedResult, message1.Int32Field);
}
[Test]
public void UnknownFieldInWrapper()
{
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
var wrapperTag = WireFormat.MakeTag(TestWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
var unknownTag = WireFormat.MakeTag(15, WireFormat.WireType.Varint);
var valueTag = WireFormat.MakeTag(Int32Value.ValueFieldNumber, WireFormat.WireType.Varint);
output.WriteTag(wrapperTag);
output.WriteLength(4); // unknownTag + value 5 + valueType + value 6, each 1 byte
output.WriteTag(unknownTag);
output.WriteInt32((int) valueTag); // Sneakily "pretend" it's a tag when it's really a value
output.WriteTag(valueTag);
output.WriteInt32(6);
output.Flush();
stream.Position = 0;
var message = TestWellKnownTypes.Parser.ParseFrom(stream);
Assert.AreEqual(6, message.Int32Field);
}
[Test]
public void ClearWithReflection()
{
// String and Bytes are the tricky ones here, as the CLR type of the property
// is the same between the wrapper and non-wrapper types.
var message = new TestWellKnownTypes { StringField = "foo" };
TestWellKnownTypes.Descriptor.Fields[TestWellKnownTypes.StringFieldFieldNumber].Accessor.Clear(message);
Assert.IsNull(message.StringField);
}
}
}

View file

@ -0,0 +1,44 @@
{
"buildOptions": {
"debugType": "portable",
"keyFile": "../../keys/Google.Protobuf.snk"
},
"configurations": {
"Debug": {
"buildOptions": {
"define": [ "DEBUG", "TRACE" ]
}
},
"Release": {
"buildOptions": {
"define": [ "RELEASE", "TRACE" ],
"optimize": true
}
}
},
"dependencies": {
"Google.Protobuf": { "target": "project" },
"NUnit": "3.4.0",
"dotnet-test-nunit": "3.4.0-alpha-2",
},
"testRunner": "nunit",
"frameworks": {
"netcoreapp1.0": {
"imports" : [ "dnxcore50", "netcoreapp1.0", "portable-net45+win8" ],
"buildOptions": {
"define": [ "PCL" ]
},
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0",
"type": "platform"
},
"System.Console": "4.0.0"
}
}
}
}

View file

@ -0,0 +1,102 @@
#!/bin/bash
function run_test() {
# Generate test proto files.
./protoc_1 -Iprotos/src -I../../../src/ --csharp_out=src/Google.Protobuf.Test \
--csharp_opt=base_namespace=Google.Protobuf \
protos/src/google/protobuf/unittest_import_proto3.proto \
protos/src/google/protobuf/unittest_import_public_proto3.proto \
protos/src/google/protobuf/unittest_well_known_types.proto
./protoc_1 -Iprotos/csharp --csharp_out=src/Google.Protobuf.Test \
--csharp_opt=base_namespace=UnitTest.Issues \
protos/csharp/protos/unittest_issues.proto
./protoc_2 -Iprotos/src --csharp_out=src/Google.Protobuf.Test \
--csharp_opt=base_namespace=Google.Protobuf \
protos/src/google/protobuf/unittest_proto3.proto \
protos/src/google/protobuf/map_unittest_proto3.proto
# Build and test.
dotnet build -c release src/Google.Protobuf src/Google.Protobuf.Test
dotnet test -c release -f netcoreapp1.0 src/Google.Protobuf.Test
}
set -ex
# Change to the script's directory.
cd $(dirname $0)
# Version of the tests (i.e., the version of protobuf from where we extracted
# these tests).
TEST_VERSION=3.0.0
# The old version of protobuf that we are testing compatibility against. This
# is usually the same as TEST_VERSION (i.e., we use the tests extracted from
# that version to test compatibility of the newest runtime against it), but it
# is also possible to use this same test set to test the compatibiilty of the
# latest version against other versions.
case "$1" in
""|3.0.0)
OLD_VERSION=3.0.0
OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0/protoc-3.0.0-linux-x86_64.exe
;;
3.0.2)
OLD_VERSION=3.0.2
OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.2/protoc-3.0.2-linux-x86_64.exe
;;
3.1.0)
OLD_VERSION=3.1.0
OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.1.0/protoc-3.1.0-linux-x86_64.exe
;;
*)
echo "[ERROR]: Unknown version number: $1"
exit 1
;;
esac
echo "Running compatibility tests with $OLD_VERSION"
# Check protoc
[ -f ../../../src/protoc ] || {
echo "[ERROR]: Please build protoc first."
exit 1
}
# Download old version protoc compiler (for linux).
wget $OLD_VERSION_PROTOC -O old_protoc
chmod +x old_protoc
# Test source compatibility. In these tests we recompile everything against
# the new runtime (including old version generated code).
# Copy the new runtime and keys.
cp ../../src/Google.Protobuf src/Google.Protobuf -r
cp ../../keys . -r
dotnet restore
# Test A.1:
# proto set 1: use old version
# proto set 2 which may import protos in set 1: use old version
cp old_protoc protoc_1
cp old_protoc protoc_2
run_test
# Test A.2:
# proto set 1: use new version
# proto set 2 which may import protos in set 1: use old version
cp ../../../src/protoc protoc_1
cp old_protoc protoc_2
run_test
# Test A.3:
# proto set 1: use old version
# proto set 2 which may import protos in set 1: use new version
cp old_protoc protoc_1
cp ../../../src/protoc protoc_2
run_test
rm protoc_1
rm protoc_2
rm old_protoc
rm keys -r
rm src/Google.Protobuf -r

View file

@ -50,9 +50,10 @@ $PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf.Test \
src/google/protobuf/unittest_well_known_types.proto
# Different base namespace to the protos above
$PROTOC -Icsharp/protos --csharp_out=csharp/src/Google.Protobuf.Test \
$PROTOC -Isrc -Icsharp/protos --csharp_out=csharp/src/Google.Protobuf.Test \
--csharp_opt=base_namespace=UnitTest.Issues \
csharp/protos/unittest_issues.proto
csharp/protos/unittest_issues.proto \
csharp/protos/unittest_custom_options_proto3.proto
# Don't specify a base namespace at all; we just want to make sure the
# results end up in TestProtos.

View file

@ -0,0 +1,336 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.
// Author: benjy@google.com (Benjy Weinberger)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// A proto file used to test the "custom options" feature of google.protobuf.
// This file is based on unittest_custom_options.proto in
// src/google/protobuf, but is modified for proto3. It could
// potentially be moved into src/google/protobuf, but currently C#
// is the only language that really needs it, as we don't support
// proto2 syntax. It's cut down significantly as proto3 only supports
// extensions for options.
syntax = "proto3";
// A custom file option (defined below).
option (file_opt1) = 9876543210;
import "google/protobuf/descriptor.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
package protobuf_unittest;
option csharp_namespace = "UnitTest.Issues.TestProtos";
// Some simple test custom options of various types.
extend google.protobuf.FileOptions {
uint64 file_opt1 = 7736974;
}
extend google.protobuf.MessageOptions {
int32 message_opt1 = 7739036;
}
extend google.protobuf.FieldOptions {
fixed64 field_opt1 = 7740936;
}
extend google.protobuf.OneofOptions {
int32 oneof_opt1 = 7740111;
}
extend google.protobuf.EnumOptions {
sfixed32 enum_opt1 = 7753576;
}
extend google.protobuf.EnumValueOptions {
int32 enum_value_opt1 = 1560678;
}
extend google.protobuf.ServiceOptions {
sint64 service_opt1 = 7887650;
}
enum MethodOpt1 {
METHODOPT1_UNSPECIFIED = 0;
METHODOPT1_VAL1 = 1;
METHODOPT1_VAL2 = 2;
}
extend google.protobuf.MethodOptions {
MethodOpt1 method_opt1 = 7890860;
}
// A test message with custom options at all possible locations (and also some
// regular options, to make sure they interact nicely).
message TestMessageWithCustomOptions {
option message_set_wire_format = false;
option (message_opt1) = -56;
string field1 = 1 [ctype=CORD,
(field_opt1)=8765432109];
oneof AnOneof {
option (oneof_opt1) = -99;
int32 oneof_field = 2;
}
enum AnEnum {
option (enum_opt1) = -789;
ANENUM_UNSPECIFIED = 0;
ANENUM_VAL1 = 1;
ANENUM_VAL2 = 2 [(enum_value_opt1) = 123];
}
}
// A test RPC service with custom options at all possible locations (and also
// some regular options, to make sure they interact nicely).
message CustomOptionFooRequest {
}
message CustomOptionFooResponse {
}
message CustomOptionFooClientMessage {
}
message CustomOptionFooServerMessage {
}
service TestServiceWithCustomOptions {
option (service_opt1) = -9876543210;
rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) {
option (method_opt1) = METHODOPT1_VAL2;
}
}
// Options of every possible field type, so we can test them all exhaustively.
message DummyMessageContainingEnum {
enum TestEnumType {
TEST_OPTION_ENUM_UNSPECIFIED = 0;
TEST_OPTION_ENUM_TYPE1 = 22;
TEST_OPTION_ENUM_TYPE2 = -23;
}
}
message DummyMessageInvalidAsOptionType {
}
extend google.protobuf.MessageOptions {
bool bool_opt = 7706090;
int32 int32_opt = 7705709;
int64 int64_opt = 7705542;
uint32 uint32_opt = 7704880;
uint64 uint64_opt = 7702367;
sint32 sint32_opt = 7701568;
sint64 sint64_opt = 7700863;
fixed32 fixed32_opt = 7700307;
fixed64 fixed64_opt = 7700194;
sfixed32 sfixed32_opt = 7698645;
sfixed64 sfixed64_opt = 7685475;
float float_opt = 7675390;
double double_opt = 7673293;
string string_opt = 7673285;
bytes bytes_opt = 7673238;
DummyMessageContainingEnum.TestEnumType enum_opt = 7673233;
DummyMessageInvalidAsOptionType message_type_opt = 7665967;
}
message CustomOptionMinIntegerValues {
option (bool_opt) = false;
option (int32_opt) = -0x80000000;
option (int64_opt) = -0x8000000000000000;
option (uint32_opt) = 0;
option (uint64_opt) = 0;
option (sint32_opt) = -0x80000000;
option (sint64_opt) = -0x8000000000000000;
option (fixed32_opt) = 0;
option (fixed64_opt) = 0;
option (sfixed32_opt) = -0x80000000;
option (sfixed64_opt) = -0x8000000000000000;
}
message CustomOptionMaxIntegerValues {
option (bool_opt) = true;
option (int32_opt) = 0x7FFFFFFF;
option (int64_opt) = 0x7FFFFFFFFFFFFFFF;
option (uint32_opt) = 0xFFFFFFFF;
option (uint64_opt) = 0xFFFFFFFFFFFFFFFF;
option (sint32_opt) = 0x7FFFFFFF;
option (sint64_opt) = 0x7FFFFFFFFFFFFFFF;
option (fixed32_opt) = 0xFFFFFFFF;
option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF;
option (sfixed32_opt) = 0x7FFFFFFF;
option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF;
}
message CustomOptionOtherValues {
option (int32_opt) = -100; // To test sign-extension.
option (float_opt) = 12.3456789;
option (double_opt) = 1.234567890123456789;
option (string_opt) = "Hello, \"World\"";
option (bytes_opt) = "Hello\0World";
option (enum_opt) = TEST_OPTION_ENUM_TYPE2;
}
message SettingRealsFromPositiveInts {
option (float_opt) = 12;
option (double_opt) = 154;
}
message SettingRealsFromNegativeInts {
option (float_opt) = -12;
option (double_opt) = -154;
}
// Options of complex message types, themselves combined and extended in
// various ways.
message ComplexOptionType1 {
int32 foo = 1;
int32 foo2 = 2;
int32 foo3 = 3;
repeated int32 foo4 = 4;
}
message ComplexOptionType2 {
ComplexOptionType1 bar = 1;
int32 baz = 2;
message ComplexOptionType4 {
int32 waldo = 1;
extend google.protobuf.MessageOptions {
ComplexOptionType4 complex_opt4 = 7633546;
}
}
ComplexOptionType4 fred = 3;
repeated ComplexOptionType4 barney = 4;
}
message ComplexOptionType3 {
int32 qux = 1;
}
extend google.protobuf.MessageOptions {
protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756;
ComplexOptionType2 complex_opt2 = 7636949;
ComplexOptionType3 complex_opt3 = 7636463;
}
// Note that we try various different ways of naming the same extension.
message VariousComplexOptions {
option (.protobuf_unittest.complex_opt1).foo = 42;
option (protobuf_unittest.complex_opt1).foo4 = 99;
option (protobuf_unittest.complex_opt1).foo4 = 88;
option (complex_opt2).baz = 987;
option (complex_opt2).bar.foo = 743;
option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971;
option (complex_opt2).fred.waldo = 321;
option (complex_opt2).barney = { waldo: 101 };
option (complex_opt2).barney = { waldo: 212 };
option (protobuf_unittest.complex_opt3).qux = 9;
}
// ------------------------------------------------------
// Definitions for testing aggregate option parsing.
// See descriptor_unittest.cc.
// A helper type used to test aggregate option parsing
message Aggregate {
int32 i = 1;
string s = 2;
// A nested object
Aggregate sub = 3;
}
// Allow Aggregate to be used as an option at all possible locations
// in the .proto grammer.
extend google.protobuf.FileOptions { Aggregate fileopt = 15478479; }
extend google.protobuf.MessageOptions { Aggregate msgopt = 15480088; }
extend google.protobuf.FieldOptions { Aggregate fieldopt = 15481374; }
extend google.protobuf.EnumOptions { Aggregate enumopt = 15483218; }
extend google.protobuf.EnumValueOptions { Aggregate enumvalopt = 15486921; }
extend google.protobuf.ServiceOptions { Aggregate serviceopt = 15497145; }
extend google.protobuf.MethodOptions { Aggregate methodopt = 15512713; }
// Try using AggregateOption at different points in the proto grammar
option (fileopt) = {
s: 'FileAnnotation'
// Also test the handling of comments
/* of both types */ i: 100
sub { s: 'NestedFileAnnotation' }
};
message AggregateMessage {
option (msgopt) = { i:101 s:'MessageAnnotation' };
int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }];
}
service AggregateService {
option (serviceopt) = { s:'ServiceAnnotation' };
rpc Method (AggregateMessage) returns (AggregateMessage) {
option (methodopt) = { s:'MethodAnnotation' };
}
}
enum AggregateEnum {
option (enumopt) = { s:'EnumAnnotation' };
UNSPECIFIED = 0;
VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }];
}
// Test custom options for nested type.
message NestedOptionType {
message NestedMessage {
option (message_opt1) = 1001;
int32 nested_field = 1 [(field_opt1) = 1002];
}
enum NestedEnum {
UNSPECIFIED = 0;
option (enum_opt1) = 1003;
NESTED_ENUM_VALUE = 1 [(enum_value_opt1) = 1004];
}
}

55
csharp/src/Google.Protobuf.Test/ByteStringTest.cs Normal file → Executable file
View file

@ -33,6 +33,10 @@
using System;
using System.Text;
using NUnit.Framework;
using System.IO;
#if !NET35
using System.Threading.Tasks;
#endif
namespace Google.Protobuf
{
@ -168,6 +172,56 @@ namespace Google.Protobuf
Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
}
[Test]
public void FromStream_Seekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
var actual = ByteString.FromStream(stream);
ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
[Test]
public void FromStream_NotSeekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
// Wrap the original stream in LimitedInputStream, which has CanSeek=false
var limitedStream = new LimitedInputStream(stream, 3);
var actual = ByteString.FromStream(limitedStream);
ByteString expected = ByteString.CopyFrom(2, 3, 4);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
#if !NET35
[Test]
public async Task FromStreamAsync_Seekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
var actual = await ByteString.FromStreamAsync(stream);
ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
[Test]
public async Task FromStreamAsync_NotSeekable()
{
var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
// Consume the first byte, just to test that it's "from current position"
stream.ReadByte();
// Wrap the original stream in LimitedInputStream, which has CanSeek=false
var limitedStream = new LimitedInputStream(stream, 3);
var actual = await ByteString.FromStreamAsync(limitedStream);
ByteString expected = ByteString.CopyFrom(2, 3, 4);
Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
}
#endif
[Test]
public void GetHashCode_Regression()
{
@ -179,6 +233,5 @@ namespace Google.Protobuf
ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4);
Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
}
}
}

View file

@ -498,6 +498,14 @@ namespace Google.Protobuf.Collections
Assert.Throws<ArgumentNullException>(() => keys.Contains(null));
}
[Test]
public void KeysCopyTo()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var keys = map.Keys.ToArray(); // Uses CopyTo internally
CollectionAssert.AreEquivalent(new[] { "foo", "x" }, keys);
}
[Test]
public void ValuesContains()
{
@ -510,6 +518,14 @@ namespace Google.Protobuf.Collections
Assert.IsFalse(values.Contains(null));
}
[Test]
public void ValuesCopyTo()
{
var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
var values = map.Values.ToArray(); // Uses CopyTo internally
CollectionAssert.AreEquivalent(new[] { "bar", "y" }, values);
}
[Test]
public void ToString_StringToString()
{

View file

@ -0,0 +1,67 @@
#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
#if NET35
using System;
using System.IO;
using NUnit.Framework;
using Google.Protobuf.Compatibility;
namespace Google.Protobuf.Test.Compatibility
{
public class StreamExtensionsTest
{
[Test]
public void CopyToNullArgument()
{
var memoryStream = new MemoryStream();
Assert.Throws<ArgumentNullException>(() => memoryStream.CopyTo(null));
}
[Test]
public void CopyToTest()
{
byte[] bytesToStream = new byte[] { 0x31, 0x08, 0xFF, 0x00 };
Stream source = new MemoryStream(bytesToStream);
Stream destination = new MemoryStream((int)source.Length);
source.CopyTo(destination);
destination.Seek(0, SeekOrigin.Begin);
Assert.AreEqual(0x31, destination.ReadByte());
Assert.AreEqual(0x08, destination.ReadByte());
Assert.AreEqual(0xFF, destination.ReadByte());
Assert.AreEqual(0x00, destination.ReadByte());
Assert.AreEqual(-1, destination.ReadByte());
}
}
}
#endif

View file

@ -34,7 +34,7 @@ using System;
using System.Collections.Generic;
using System.Reflection;
#if !DOTNET35
#if !NET35
namespace Google.Protobuf.Compatibility
{
public class TypeExtensionsTest

5
csharp/src/Google.Protobuf.Test/FieldCodecTest.cs Normal file → Executable file
View file

@ -158,7 +158,9 @@ namespace Google.Protobuf
{
// WriteTagAndValue ignores default values
var stream = new MemoryStream();
var codedOutput = new CodedOutputStream(stream);
CodedOutputStream codedOutput;
#if !NET35
codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
codedOutput.Flush();
Assert.AreEqual(0, stream.Position);
@ -167,6 +169,7 @@ namespace Google.Protobuf
{
Assert.AreEqual(default(T), codec.DefaultValue);
}
#endif
// The plain ValueWriter/ValueReader delegates don't.
if (codec.DefaultValue != null) // This part isn't appropriate for message types.

View file

@ -52,7 +52,7 @@ namespace Google.Protobuf
[Test]
public void DefaultValues_WhenOmitted()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(formatDefaultValues: false));
var formatter = JsonFormatter.Default;
AssertJson("{ }", formatter.Format(new ForeignMessage()));
AssertJson("{ }", formatter.Format(new TestAllTypes()));
@ -62,10 +62,39 @@ namespace Google.Protobuf
[Test]
public void DefaultValues_WhenIncluded()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(formatDefaultValues: true));
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
AssertJson("{ 'c': 0 }", formatter.Format(new ForeignMessage()));
}
[Test]
public void EnumAllowAlias()
{
var message = new TestEnumAllowAlias
{
Value = TestEnumWithDupValue.Foo2,
};
var actualText = JsonFormatter.Default.Format(message);
var expectedText = "{ 'value': 'FOO1' }";
AssertJson(expectedText, actualText);
}
[Test]
public void EnumAsInt()
{
var message = new TestAllTypes
{
SingleForeignEnum = ForeignEnum.ForeignBar,
RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo }
};
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatEnumsAsIntegers(true));
var actualText = formatter.Format(message);
var expectedText = "{ " +
"'singleForeignEnum': 5, " +
"'repeatedForeignEnum': [ 6, 100, 4 ]" +
" }";
AssertJson(expectedText, actualText);
}
[Test]
public void AllSingleFields()
{
@ -254,9 +283,9 @@ namespace Google.Protobuf
}
// We should get the same result both with and without "format default values".
var formatter = new JsonFormatter(new JsonFormatter.Settings(false));
var formatter = JsonFormatter.Default;
AssertJson(expectedJson, formatter.Format(message));
formatter = new JsonFormatter(new JsonFormatter.Settings(true));
formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
AssertJson(expectedJson, formatter.Format(message));
}
@ -288,7 +317,7 @@ namespace Google.Protobuf
{
// The actual JSON here is very large because there are lots of fields. Just test a couple of them.
var message = new TestWellKnownTypes { Int32Field = 10 };
var formatter = new JsonFormatter(new JsonFormatter.Settings(true));
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
var actualJson = formatter.Format(message);
Assert.IsTrue(actualJson.Contains("\"int64Field\": null"));
Assert.IsFalse(actualJson.Contains("\"int32Field\": null"));
@ -297,7 +326,7 @@ namespace Google.Protobuf
[Test]
public void OutputIsInNumericFieldOrder_NoDefaults()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(false));
var formatter = JsonFormatter.Default;
var message = new TestJsonFieldOrdering { PlainString = "p1", PlainInt32 = 2 };
AssertJson("{ 'plainString': 'p1', 'plainInt32': 2 }", formatter.Format(message));
message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" };
@ -309,7 +338,7 @@ namespace Google.Protobuf
[Test]
public void OutputIsInNumericFieldOrder_WithDefaults()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(true));
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
var message = new TestJsonFieldOrdering();
AssertJson("{ 'plainString': '', 'plainInt32': 0 }", formatter.Format(message));
message = new TestJsonFieldOrdering { O1Int32 = 5, O2String = "o2", PlainInt32 = 10, PlainString = "plain" };
@ -473,7 +502,7 @@ namespace Google.Protobuf
[Test]
public void AnyWellKnownType()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(Timestamp.Descriptor)));
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(Timestamp.Descriptor)));
var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
var any = Any.Pack(timestamp);
AssertJson("{ '@type': 'type.googleapis.com/google.protobuf.Timestamp', 'value': '1673-06-19T12:34:56Z' }", formatter.Format(any));
@ -482,7 +511,7 @@ namespace Google.Protobuf
[Test]
public void AnyMessageType()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } };
var any = Any.Pack(message);
AssertJson("{ '@type': 'type.googleapis.com/protobuf_unittest.TestAllTypes', 'singleInt32': 10, 'singleNestedMessage': { 'bb': 20 } }", formatter.Format(any));
@ -491,7 +520,7 @@ namespace Google.Protobuf
[Test]
public void AnyMessageType_CustomPrefix()
{
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
var message = new TestAllTypes { SingleInt32 = 10 };
var any = Any.Pack(message, "foo.bar/baz");
AssertJson("{ '@type': 'foo.bar/baz/protobuf_unittest.TestAllTypes', 'singleInt32': 10 }", formatter.Format(any));
@ -501,7 +530,7 @@ namespace Google.Protobuf
public void AnyNested()
{
var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor);
var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithTypeRegistry(registry));
// Nest an Any as the value of an Any.
var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 };

View file

@ -0,0 +1,271 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2017 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.Reflection;
using Google.Protobuf.WellKnownTypes;
using NUnit.Framework;
using System.IO;
using System.Linq;
using UnitTest.Issues.TestProtos;
using static Google.Protobuf.WireFormat;
using static UnitTest.Issues.TestProtos.ComplexOptionType2.Types;
using static UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types;
using static Google.Protobuf.Test.Reflection.CustomOptionNumber;
namespace Google.Protobuf.Test.Reflection
{
// Internal enum to allow us to use "using static" for convenience.
// These are the options defined in unittest_custom_options_proto3.proto
internal enum CustomOptionNumber
{
FileOpt1 = 7736974,
MessageOpt1 = 7739036,
FieldOpt1 = 7740936,
OneofOpt1 = 7740111,
EnumOpt1 = 7753576,
EnumValueOpt1 = 1560678,
ServiceOpt1 = 7887650,
MethodOpt1 = 7890860,
// All message options...
BoolOpt = 7706090,
Int32Opt = 7705709,
Int64Opt = 7705542,
UInt32Opt = 7704880,
UInt64Opt = 7702367,
SInt32Opt = 7701568,
SInt64Opt = 7700863,
Fixed32Opt = 7700307,
Fixed64Opt = 7700194,
SFixed32Opt = 7698645,
SFixed64Opt = 7685475,
FloatOpt = 7675390,
DoubleOpt = 7673293,
StringOpt = 7673285,
BytesOpt = 7673238,
EnumOpt = 7673233,
MessageTypeOpt = 7665967,
// Miscellaneous
ComplexOpt4 = 7633546,
ComplexOpt1 = 7646756,
ComplexOpt2 = 7636949,
ComplexOpt3 = 7636463,
// Aggregates
AggregateFileOpt = 15478479,
AggregateMsgOpt = 15480088,
AggregateFieldOpt = 15481374,
AggregateEnumOpt = 15483218,
AggregateEnumValueOpt = 15486921,
AggregateServiceOpt = 15497145,
AggregateMethodOpt = 15512713,
}
/// <summary>
/// The majority of the testing here is done via parsed descriptors. That's simpler to
/// achieve (and more important) than constructing a CodedInputStream manually.
/// </summary>
public class CustomOptionsTest
{
delegate bool OptionFetcher<T>(int field, out T value);
[Test]
public void EmptyOptionsIsShared()
{
var structOptions = Struct.Descriptor.CustomOptions;
var timestampOptions = Struct.Descriptor.CustomOptions;
Assert.AreSame(structOptions, timestampOptions);
}
[Test]
public void SimpleIntegerTest()
{
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(MakeTag(1, WireType.Varint));
output.WriteInt32(1234567);
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.ReadTag();
var options = CustomOptions.Empty;
options = options.ReadOrSkipUnknownField(input);
int intValue;
Assert.True(options.TryGetInt32(1, out intValue));
Assert.AreEqual(1234567, intValue);
string stringValue;
// No ByteString stored values
Assert.False(options.TryGetString(1, out stringValue));
// Nothing stored for field 2
Assert.False(options.TryGetInt32(2, out intValue));
}
[Test]
public void SimpleStringTest()
{
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
output.WriteTag(MakeTag(1, WireType.LengthDelimited));
output.WriteString("value");
output.Flush();
stream.Position = 0;
var input = new CodedInputStream(stream);
input.ReadTag();
var options = CustomOptions.Empty;
options = options.ReadOrSkipUnknownField(input);
string stringValue;
Assert.True(options.TryGetString(1, out stringValue));
Assert.AreEqual("value", stringValue);
int intValue;
// No numeric stored values
Assert.False(options.TryGetInt32(1, out intValue));
// Nothing stored for field 2
Assert.False(options.TryGetString(2, out stringValue));
}
[Test]
public void ScalarOptions()
{
var options = CustomOptionOtherValues.Descriptor.CustomOptions;
AssertOption(-100, options.TryGetInt32, Int32Opt);
AssertOption(12.3456789f, options.TryGetFloat, FloatOpt);
AssertOption(1.234567890123456789d, options.TryGetDouble, DoubleOpt);
AssertOption("Hello, \"World\"", options.TryGetString, StringOpt);
AssertOption(ByteString.CopyFromUtf8("Hello\0World"), options.TryGetBytes, BytesOpt);
AssertOption((int) TestEnumType.TestOptionEnumType2, options.TryGetInt32, EnumOpt);
}
[Test]
public void MessageOptions()
{
var options = VariousComplexOptions.Descriptor.CustomOptions;
AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, options.TryGetMessage, ComplexOpt1);
AssertOption(new ComplexOptionType2
{
Baz = 987, Bar = new ComplexOptionType1 { Foo = 743 },
Fred = new ComplexOptionType4 { Waldo = 321 },
Barney = { new ComplexOptionType4 { Waldo = 101 }, new ComplexOptionType4 { Waldo = 212 } }
},
options.TryGetMessage, ComplexOpt2);
AssertOption(new ComplexOptionType3 { Qux = 9 }, options.TryGetMessage, ComplexOpt3);
}
[Test]
public void OptionLocations()
{
var fileOptions = UnittestCustomOptionsProto3Reflection.Descriptor.CustomOptions;
AssertOption(9876543210UL, fileOptions.TryGetUInt64, FileOpt1);
var messageOptions = TestMessageWithCustomOptions.Descriptor.CustomOptions;
AssertOption(-56, messageOptions.TryGetInt32, MessageOpt1);
var fieldOptions = TestMessageWithCustomOptions.Descriptor.Fields["field1"] .CustomOptions;
AssertOption(8765432109UL, fieldOptions.TryGetFixed64, FieldOpt1);
var oneofOptions = TestMessageWithCustomOptions.Descriptor.Oneofs[0].CustomOptions;
AssertOption(-99, oneofOptions.TryGetInt32, OneofOpt1);
var enumOptions = TestMessageWithCustomOptions.Descriptor.EnumTypes[0].CustomOptions;
AssertOption(-789, enumOptions.TryGetSFixed32, EnumOpt1);
var enumValueOptions = TestMessageWithCustomOptions.Descriptor.EnumTypes[0].FindValueByNumber(2).CustomOptions;
AssertOption(123, enumValueOptions.TryGetInt32, EnumValueOpt1);
var service = UnittestCustomOptionsProto3Reflection.Descriptor.Services
.Single(s => s.Name == "TestServiceWithCustomOptions");
var serviceOptions = service.CustomOptions;
AssertOption(-9876543210, serviceOptions.TryGetSInt64, ServiceOpt1);
var methodOptions = service.Methods[0].CustomOptions;
AssertOption((int) UnitTest.Issues.TestProtos.MethodOpt1.Val2, methodOptions.TryGetInt32, CustomOptionNumber.MethodOpt1);
}
[Test]
public void MinValues()
{
var options = CustomOptionMinIntegerValues.Descriptor.CustomOptions;
AssertOption(false, options.TryGetBool, BoolOpt);
AssertOption(int.MinValue, options.TryGetInt32, Int32Opt);
AssertOption(long.MinValue, options.TryGetInt64, Int64Opt);
AssertOption(uint.MinValue, options.TryGetUInt32, UInt32Opt);
AssertOption(ulong.MinValue, options.TryGetUInt64, UInt64Opt);
AssertOption(int.MinValue, options.TryGetSInt32, SInt32Opt);
AssertOption(long.MinValue, options.TryGetSInt64, SInt64Opt);
AssertOption(uint.MinValue, options.TryGetUInt32, Fixed32Opt);
AssertOption(ulong.MinValue, options.TryGetUInt64, Fixed64Opt);
AssertOption(int.MinValue, options.TryGetInt32, SFixed32Opt);
AssertOption(long.MinValue, options.TryGetInt64, SFixed64Opt);
}
[Test]
public void MaxValues()
{
var options = CustomOptionMaxIntegerValues.Descriptor.CustomOptions;
AssertOption(true, options.TryGetBool, BoolOpt);
AssertOption(int.MaxValue, options.TryGetInt32, Int32Opt);
AssertOption(long.MaxValue, options.TryGetInt64, Int64Opt);
AssertOption(uint.MaxValue, options.TryGetUInt32, UInt32Opt);
AssertOption(ulong.MaxValue, options.TryGetUInt64, UInt64Opt);
AssertOption(int.MaxValue, options.TryGetSInt32, SInt32Opt);
AssertOption(long.MaxValue, options.TryGetSInt64, SInt64Opt);
AssertOption(uint.MaxValue, options.TryGetFixed32, Fixed32Opt);
AssertOption(ulong.MaxValue, options.TryGetFixed64, Fixed64Opt);
AssertOption(int.MaxValue, options.TryGetSFixed32, SFixed32Opt);
AssertOption(long.MaxValue, options.TryGetSFixed64, SFixed64Opt);
}
[Test]
public void AggregateOptions()
{
// Just two examples
var messageOptions = AggregateMessage.Descriptor.CustomOptions;
AssertOption(new Aggregate { I = 101, S = "MessageAnnotation" }, messageOptions.TryGetMessage, AggregateMsgOpt);
var fieldOptions = AggregateMessage.Descriptor.Fields["fieldname"].CustomOptions;
AssertOption(new Aggregate { S = "FieldAnnotation" }, fieldOptions.TryGetMessage, AggregateFieldOpt);
}
private void AssertOption<T>(T expected, OptionFetcher<T> fetcher, CustomOptionNumber field)
{
T actual;
Assert.IsTrue(fetcher((int) field, out actual));
Assert.AreEqual(expected, actual);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -85,70 +85,72 @@ namespace Google.Protobuf.TestProtos {
"ZXN0TXV0dWFsUmVjdXJzaW9uQRIzCgJiYhgBIAEoCzInLnByb3RvYnVmX3Vu",
"aXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CImIKFFRlc3RNdXR1YWxSZWN1",
"cnNpb25CEjIKAWEYASABKAsyJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0",
"dWFsUmVjdXJzaW9uQRIWCg5vcHRpb25hbF9pbnQzMhgCIAEoBSLrAgoXVGVz",
"dENhbWVsQ2FzZUZpZWxkTmFtZXMSFgoOUHJpbWl0aXZlRmllbGQYASABKAUS",
"EwoLU3RyaW5nRmllbGQYAiABKAkSMQoJRW51bUZpZWxkGAMgASgOMh4ucHJv",
"dG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0SNwoMTWVzc2FnZUZpZWxkGAQg",
"ASgLMiEucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2USHgoWUmVw",
"ZWF0ZWRQcmltaXRpdmVGaWVsZBgHIAMoBRIbChNSZXBlYXRlZFN0cmluZ0Zp",
"ZWxkGAggAygJEjkKEVJlcGVhdGVkRW51bUZpZWxkGAkgAygOMh4ucHJvdG9i",
"dWZfdW5pdHRlc3QuRm9yZWlnbkVudW0SPwoUUmVwZWF0ZWRNZXNzYWdlRmll",
"bGQYCiADKAsyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSLH",
"AQoSVGVzdEZpZWxkT3JkZXJpbmdzEhEKCW15X3N0cmluZxgLIAEoCRIOCgZt",
"eV9pbnQYASABKAMSEAoIbXlfZmxvYXQYZSABKAISUwoVc2luZ2xlX25lc3Rl",
"ZF9tZXNzYWdlGMgBIAEoCzIzLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVs",
"ZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlGicKDU5lc3RlZE1lc3NhZ2USCgoC",
"b28YAiABKAMSCgoCYmIYASABKAUiSwoRU3BhcnNlRW51bU1lc3NhZ2USNgoL",
"c3BhcnNlX2VudW0YASABKA4yIS5wcm90b2J1Zl91bml0dGVzdC5UZXN0U3Bh",
"cnNlRW51bSIZCglPbmVTdHJpbmcSDAoEZGF0YRgBIAEoCSIaCgpNb3JlU3Ry",
"aW5nEgwKBGRhdGEYASADKAkiGAoIT25lQnl0ZXMSDAoEZGF0YRgBIAEoDCIZ",
"CglNb3JlQnl0ZXMSDAoEZGF0YRgBIAEoDCIcCgxJbnQzMk1lc3NhZ2USDAoE",
"ZGF0YRgBIAEoBSIdCg1VaW50MzJNZXNzYWdlEgwKBGRhdGEYASABKA0iHAoM",
"SW50NjRNZXNzYWdlEgwKBGRhdGEYASABKAMiHQoNVWludDY0TWVzc2FnZRIM",
"CgRkYXRhGAEgASgEIhsKC0Jvb2xNZXNzYWdlEgwKBGRhdGEYASABKAgicwoJ",
"VGVzdE9uZW9mEhEKB2Zvb19pbnQYASABKAVIABIUCgpmb29fc3RyaW5nGAIg",
"ASgJSAASNgoLZm9vX21lc3NhZ2UYAyABKAsyHy5wcm90b2J1Zl91bml0dGVz",
"dC5UZXN0QWxsVHlwZXNIAEIFCgNmb28iqgMKD1Rlc3RQYWNrZWRUeXBlcxIY",
"CgxwYWNrZWRfaW50MzIYWiADKAVCAhABEhgKDHBhY2tlZF9pbnQ2NBhbIAMo",
"A0ICEAESGQoNcGFja2VkX3VpbnQzMhhcIAMoDUICEAESGQoNcGFja2VkX3Vp",
"bnQ2NBhdIAMoBEICEAESGQoNcGFja2VkX3NpbnQzMhheIAMoEUICEAESGQoN",
"cGFja2VkX3NpbnQ2NBhfIAMoEkICEAESGgoOcGFja2VkX2ZpeGVkMzIYYCAD",
"KAdCAhABEhoKDnBhY2tlZF9maXhlZDY0GGEgAygGQgIQARIbCg9wYWNrZWRf",
"c2ZpeGVkMzIYYiADKA9CAhABEhsKD3BhY2tlZF9zZml4ZWQ2NBhjIAMoEEIC",
"EAESGAoMcGFja2VkX2Zsb2F0GGQgAygCQgIQARIZCg1wYWNrZWRfZG91Ymxl",
"GGUgAygBQgIQARIXCgtwYWNrZWRfYm9vbBhmIAMoCEICEAESNwoLcGFja2Vk",
"X2VudW0YZyADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bUIC",
"EAEiyAMKEVRlc3RVbnBhY2tlZFR5cGVzEhoKDnVucGFja2VkX2ludDMyGFog",
"AygFQgIQABIaCg51bnBhY2tlZF9pbnQ2NBhbIAMoA0ICEAASGwoPdW5wYWNr",
"ZWRfdWludDMyGFwgAygNQgIQABIbCg91bnBhY2tlZF91aW50NjQYXSADKARC",
"AhAAEhsKD3VucGFja2VkX3NpbnQzMhheIAMoEUICEAASGwoPdW5wYWNrZWRf",
"c2ludDY0GF8gAygSQgIQABIcChB1bnBhY2tlZF9maXhlZDMyGGAgAygHQgIQ",
"ABIcChB1bnBhY2tlZF9maXhlZDY0GGEgAygGQgIQABIdChF1bnBhY2tlZF9z",
"Zml4ZWQzMhhiIAMoD0ICEAASHQoRdW5wYWNrZWRfc2ZpeGVkNjQYYyADKBBC",
"AhAAEhoKDnVucGFja2VkX2Zsb2F0GGQgAygCQgIQABIbCg91bnBhY2tlZF9k",
"b3VibGUYZSADKAFCAhAAEhkKDXVucGFja2VkX2Jvb2wYZiADKAhCAhAAEjkK",
"DXVucGFja2VkX2VudW0YZyADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3Jl",
"aWduRW51bUICEAAiwAEKI1Rlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRh",
"Z1NpemVzEhgKEHJlcGVhdGVkX2ZpeGVkMzIYDCADKAcSFgoOcmVwZWF0ZWRf",
"aW50MzIYDSADKAUSGQoQcmVwZWF0ZWRfZml4ZWQ2NBj+DyADKAYSFwoOcmVw",
"ZWF0ZWRfaW50NjQY/w8gAygDEhgKDnJlcGVhdGVkX2Zsb2F0GP7/DyADKAIS",
"GQoPcmVwZWF0ZWRfdWludDY0GP//DyADKAQiKAobVGVzdENvbW1lbnRJbmpl",
"Y3Rpb25NZXNzYWdlEgkKAWEYASABKAkiDAoKRm9vUmVxdWVzdCINCgtGb29S",
"ZXNwb25zZSISChBGb29DbGllbnRNZXNzYWdlIhIKEEZvb1NlcnZlck1lc3Nh",
"Z2UiDAoKQmFyUmVxdWVzdCINCgtCYXJSZXNwb25zZSpZCgtGb3JlaWduRW51",
"bRIXChNGT1JFSUdOX1VOU1BFQ0lGSUVEEAASDwoLRk9SRUlHTl9GT08QBBIP",
"CgtGT1JFSUdOX0JBUhAFEg8KC0ZPUkVJR05fQkFaEAYqdQoUVGVzdEVudW1X",
"aXRoRHVwVmFsdWUSKAokVEVTVF9FTlVNX1dJVEhfRFVQX1ZBTFVFX1VOU1BF",
"Q0lGSUVEEAASCAoERk9PMRABEggKBEJBUjEQAhIHCgNCQVoQAxIICgRGT08y",
"EAESCAoEQkFSMhACGgIQASqdAQoOVGVzdFNwYXJzZUVudW0SIAocVEVTVF9T",
"UEFSU0VfRU5VTV9VTlNQRUNJRklFRBAAEgwKCFNQQVJTRV9BEHsSDgoIU1BB",
"UlNFX0IQpucDEg8KCFNQQVJTRV9DELKxgAYSFQoIU1BBUlNFX0QQ8f//////",
"////ARIVCghTUEFSU0VfRRC03vz///////8BEgwKCFNQQVJTRV9HEAIymQEK",
"C1Rlc3RTZXJ2aWNlEkQKA0ZvbxIdLnByb3RvYnVmX3VuaXR0ZXN0LkZvb1Jl",
"cXVlc3QaHi5wcm90b2J1Zl91bml0dGVzdC5Gb29SZXNwb25zZRJECgNCYXIS",
"HS5wcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1ZXN0Gh4ucHJvdG9idWZfdW5p",
"dHRlc3QuQmFyUmVzcG9uc2VCOkINVW5pdHRlc3RQcm90b0gBgAEBiAEBkAEB",
"+AEBqgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
"dWFsUmVjdXJzaW9uQRIWCg5vcHRpb25hbF9pbnQzMhgCIAEoBSJMChJUZXN0",
"RW51bUFsbG93QWxpYXMSNgoFdmFsdWUYASABKA4yJy5wcm90b2J1Zl91bml0",
"dGVzdC5UZXN0RW51bVdpdGhEdXBWYWx1ZSLrAgoXVGVzdENhbWVsQ2FzZUZp",
"ZWxkTmFtZXMSFgoOUHJpbWl0aXZlRmllbGQYASABKAUSEwoLU3RyaW5nRmll",
"bGQYAiABKAkSMQoJRW51bUZpZWxkGAMgASgOMh4ucHJvdG9idWZfdW5pdHRl",
"c3QuRm9yZWlnbkVudW0SNwoMTWVzc2FnZUZpZWxkGAQgASgLMiEucHJvdG9i",
"dWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2USHgoWUmVwZWF0ZWRQcmltaXRp",
"dmVGaWVsZBgHIAMoBRIbChNSZXBlYXRlZFN0cmluZ0ZpZWxkGAggAygJEjkK",
"EVJlcGVhdGVkRW51bUZpZWxkGAkgAygOMh4ucHJvdG9idWZfdW5pdHRlc3Qu",
"Rm9yZWlnbkVudW0SPwoUUmVwZWF0ZWRNZXNzYWdlRmllbGQYCiADKAsyIS5w",
"cm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSLHAQoSVGVzdEZpZWxk",
"T3JkZXJpbmdzEhEKCW15X3N0cmluZxgLIAEoCRIOCgZteV9pbnQYASABKAMS",
"EAoIbXlfZmxvYXQYZSABKAISUwoVc2luZ2xlX25lc3RlZF9tZXNzYWdlGMgB",
"IAEoCzIzLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5O",
"ZXN0ZWRNZXNzYWdlGicKDU5lc3RlZE1lc3NhZ2USCgoCb28YAiABKAMSCgoC",
"YmIYASABKAUiSwoRU3BhcnNlRW51bU1lc3NhZ2USNgoLc3BhcnNlX2VudW0Y",
"ASABKA4yIS5wcm90b2J1Zl91bml0dGVzdC5UZXN0U3BhcnNlRW51bSIZCglP",
"bmVTdHJpbmcSDAoEZGF0YRgBIAEoCSIaCgpNb3JlU3RyaW5nEgwKBGRhdGEY",
"ASADKAkiGAoIT25lQnl0ZXMSDAoEZGF0YRgBIAEoDCIZCglNb3JlQnl0ZXMS",
"DAoEZGF0YRgBIAEoDCIcCgxJbnQzMk1lc3NhZ2USDAoEZGF0YRgBIAEoBSId",
"Cg1VaW50MzJNZXNzYWdlEgwKBGRhdGEYASABKA0iHAoMSW50NjRNZXNzYWdl",
"EgwKBGRhdGEYASABKAMiHQoNVWludDY0TWVzc2FnZRIMCgRkYXRhGAEgASgE",
"IhsKC0Jvb2xNZXNzYWdlEgwKBGRhdGEYASABKAgicwoJVGVzdE9uZW9mEhEK",
"B2Zvb19pbnQYASABKAVIABIUCgpmb29fc3RyaW5nGAIgASgJSAASNgoLZm9v",
"X21lc3NhZ2UYAyABKAsyHy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlw",
"ZXNIAEIFCgNmb28iqgMKD1Rlc3RQYWNrZWRUeXBlcxIYCgxwYWNrZWRfaW50",
"MzIYWiADKAVCAhABEhgKDHBhY2tlZF9pbnQ2NBhbIAMoA0ICEAESGQoNcGFj",
"a2VkX3VpbnQzMhhcIAMoDUICEAESGQoNcGFja2VkX3VpbnQ2NBhdIAMoBEIC",
"EAESGQoNcGFja2VkX3NpbnQzMhheIAMoEUICEAESGQoNcGFja2VkX3NpbnQ2",
"NBhfIAMoEkICEAESGgoOcGFja2VkX2ZpeGVkMzIYYCADKAdCAhABEhoKDnBh",
"Y2tlZF9maXhlZDY0GGEgAygGQgIQARIbCg9wYWNrZWRfc2ZpeGVkMzIYYiAD",
"KA9CAhABEhsKD3BhY2tlZF9zZml4ZWQ2NBhjIAMoEEICEAESGAoMcGFja2Vk",
"X2Zsb2F0GGQgAygCQgIQARIZCg1wYWNrZWRfZG91YmxlGGUgAygBQgIQARIX",
"CgtwYWNrZWRfYm9vbBhmIAMoCEICEAESNwoLcGFja2VkX2VudW0YZyADKA4y",
"Hi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bUICEAEiyAMKEVRlc3RV",
"bnBhY2tlZFR5cGVzEhoKDnVucGFja2VkX2ludDMyGFogAygFQgIQABIaCg51",
"bnBhY2tlZF9pbnQ2NBhbIAMoA0ICEAASGwoPdW5wYWNrZWRfdWludDMyGFwg",
"AygNQgIQABIbCg91bnBhY2tlZF91aW50NjQYXSADKARCAhAAEhsKD3VucGFj",
"a2VkX3NpbnQzMhheIAMoEUICEAASGwoPdW5wYWNrZWRfc2ludDY0GF8gAygS",
"QgIQABIcChB1bnBhY2tlZF9maXhlZDMyGGAgAygHQgIQABIcChB1bnBhY2tl",
"ZF9maXhlZDY0GGEgAygGQgIQABIdChF1bnBhY2tlZF9zZml4ZWQzMhhiIAMo",
"D0ICEAASHQoRdW5wYWNrZWRfc2ZpeGVkNjQYYyADKBBCAhAAEhoKDnVucGFj",
"a2VkX2Zsb2F0GGQgAygCQgIQABIbCg91bnBhY2tlZF9kb3VibGUYZSADKAFC",
"AhAAEhkKDXVucGFja2VkX2Jvb2wYZiADKAhCAhAAEjkKDXVucGFja2VkX2Vu",
"dW0YZyADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bUICEAAi",
"wAEKI1Rlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzEhgKEHJl",
"cGVhdGVkX2ZpeGVkMzIYDCADKAcSFgoOcmVwZWF0ZWRfaW50MzIYDSADKAUS",
"GQoQcmVwZWF0ZWRfZml4ZWQ2NBj+DyADKAYSFwoOcmVwZWF0ZWRfaW50NjQY",
"/w8gAygDEhgKDnJlcGVhdGVkX2Zsb2F0GP7/DyADKAISGQoPcmVwZWF0ZWRf",
"dWludDY0GP//DyADKAQiKAobVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdl",
"EgkKAWEYASABKAkiDAoKRm9vUmVxdWVzdCINCgtGb29SZXNwb25zZSISChBG",
"b29DbGllbnRNZXNzYWdlIhIKEEZvb1NlcnZlck1lc3NhZ2UiDAoKQmFyUmVx",
"dWVzdCINCgtCYXJSZXNwb25zZSpZCgtGb3JlaWduRW51bRIXChNGT1JFSUdO",
"X1VOU1BFQ0lGSUVEEAASDwoLRk9SRUlHTl9GT08QBBIPCgtGT1JFSUdOX0JB",
"UhAFEg8KC0ZPUkVJR05fQkFaEAYqdQoUVGVzdEVudW1XaXRoRHVwVmFsdWUS",
"KAokVEVTVF9FTlVNX1dJVEhfRFVQX1ZBTFVFX1VOU1BFQ0lGSUVEEAASCAoE",
"Rk9PMRABEggKBEJBUjEQAhIHCgNCQVoQAxIICgRGT08yEAESCAoEQkFSMhAC",
"GgIQASqdAQoOVGVzdFNwYXJzZUVudW0SIAocVEVTVF9TUEFSU0VfRU5VTV9V",
"TlNQRUNJRklFRBAAEgwKCFNQQVJTRV9BEHsSDgoIU1BBUlNFX0IQpucDEg8K",
"CFNQQVJTRV9DELKxgAYSFQoIU1BBUlNFX0QQ8f//////////ARIVCghTUEFS",
"U0VfRRC03vz///////8BEgwKCFNQQVJTRV9HEAIymQEKC1Rlc3RTZXJ2aWNl",
"EkQKA0ZvbxIdLnByb3RvYnVmX3VuaXR0ZXN0LkZvb1JlcXVlc3QaHi5wcm90",
"b2J1Zl91bml0dGVzdC5Gb29SZXNwb25zZRJECgNCYXISHS5wcm90b2J1Zl91",
"bml0dGVzdC5CYXJSZXF1ZXN0Gh4ucHJvdG9idWZfdW5pdHRlc3QuQmFyUmVz",
"cG9uc2VCOkINVW5pdHRlc3RQcm90b0gBgAEBiAEBkAEB+AEBqgIaR29vZ2xl",
"LlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportProto3Reflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ForeignEnum), typeof(global::Google.Protobuf.TestProtos.TestEnumWithDupValue), typeof(global::Google.Protobuf.TestProtos.TestSparseEnum), }, new pbr::GeneratedClrTypeInfo[] {
@ -162,6 +164,7 @@ namespace Google.Protobuf.TestProtos {
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestRecursiveMessage), global::Google.Protobuf.TestProtos.TestRecursiveMessage.Parser, new[]{ "A", "I" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionA), global::Google.Protobuf.TestProtos.TestMutualRecursionA.Parser, new[]{ "Bb" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionB), global::Google.Protobuf.TestProtos.TestMutualRecursionB.Parser, new[]{ "A", "OptionalInt32" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestEnumAllowAlias), global::Google.Protobuf.TestProtos.TestEnumAllowAlias.Parser, new[]{ "Value" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames), global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames.Parser, new[]{ "PrimitiveField", "StringField", "EnumField", "MessageField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedEnumField", "RepeatedMessageField" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings), global::Google.Protobuf.TestProtos.TestFieldOrderings.Parser, new[]{ "MyString", "MyInt", "MyFloat", "SingleNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage.Parser, new[]{ "Oo", "Bb" }, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.SparseEnumMessage), global::Google.Protobuf.TestProtos.SparseEnumMessage.Parser, new[]{ "SparseEnum" }, null, null, null),
@ -206,8 +209,8 @@ namespace Google.Protobuf.TestProtos {
[pbr::OriginalName("FOO1")] Foo1 = 1,
[pbr::OriginalName("BAR1")] Bar1 = 2,
[pbr::OriginalName("BAZ")] Baz = 3,
[pbr::OriginalName("FOO2")] Foo2 = 1,
[pbr::OriginalName("BAR2")] Bar2 = 2,
[pbr::OriginalName("FOO2", PreferredAlias = false)] Foo2 = 1,
[pbr::OriginalName("BAR2", PreferredAlias = false)] Bar2 = 2,
}
/// <summary>
@ -2939,6 +2942,123 @@ namespace Google.Protobuf.TestProtos {
}
public sealed partial class TestEnumAllowAlias : pb::IMessage<TestEnumAllowAlias> {
private static readonly pb::MessageParser<TestEnumAllowAlias> _parser = new pb::MessageParser<TestEnumAllowAlias>(() => new TestEnumAllowAlias());
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestEnumAllowAlias> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[10]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestEnumAllowAlias() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestEnumAllowAlias(TestEnumAllowAlias other) : this() {
value_ = other.value_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestEnumAllowAlias Clone() {
return new TestEnumAllowAlias(this);
}
/// <summary>Field number for the "value" field.</summary>
public const int ValueFieldNumber = 1;
private global::Google.Protobuf.TestProtos.TestEnumWithDupValue value_ = 0;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestEnumWithDupValue Value {
get { return value_; }
set {
value_ = value;
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestEnumAllowAlias);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestEnumAllowAlias other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (Value != other.Value) return false;
return true;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != 0) hash ^= Value.GetHashCode();
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) Value);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Value);
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestEnumAllowAlias other) {
if (other == null) {
return;
}
if (other.Value != 0) {
Value = other.Value;
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
break;
case 8: {
value_ = (global::Google.Protobuf.TestProtos.TestEnumWithDupValue) input.ReadEnum();
break;
}
}
}
}
}
/// <summary>
/// Test message with CamelCase field names. This violates Protocol Buffer
/// standard style.
@ -2950,7 +3070,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[10]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[11]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -3243,7 +3363,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[11]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[12]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -3607,7 +3727,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[12]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[13]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -3727,7 +3847,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[13]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[14]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -3844,7 +3964,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[14]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[15]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -3953,7 +4073,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[15]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[16]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4070,7 +4190,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[16]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[17]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4190,7 +4310,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[17]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[18]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4307,7 +4427,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[18]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[19]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4424,7 +4544,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[19]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[20]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4541,7 +4661,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[20]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[21]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4658,7 +4778,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[21]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[22]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4778,7 +4898,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[22]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[23]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -4990,7 +5110,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[23]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[24]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -5377,7 +5497,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[24]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[25]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -5760,7 +5880,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[25]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[26]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -5989,7 +6109,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[26]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[27]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -6112,7 +6232,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[27]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[28]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -6201,7 +6321,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[28]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[29]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -6290,7 +6410,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[29]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[30]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -6379,7 +6499,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[30]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[31]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -6468,7 +6588,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[31]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[32]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -6557,7 +6677,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[32]; }
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[33]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]

View file

@ -20,13 +20,14 @@
"dependencies": {
"Google.Protobuf": { "target": "project" },
"NUnit": "3.4.0",
"dotnet-test-nunit": "3.4.0-alpha-2"
"dotnet-test-nunit": "3.4.0-beta-3",
"NUnit": "3.6.0"
},
"testRunner": "nunit",
"frameworks": {
"net451": {},
"netcoreapp1.0": {
"imports" : [ "dnxcore50", "netcoreapp1.0", "portable-net45+win8" ],
"buildOptions": {
@ -41,4 +42,4 @@
}
}
}
}
}

56
csharp/src/Google.Protobuf/ByteString.cs Normal file → Executable file
View file

@ -35,6 +35,13 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
#if !NET35
using System.Threading;
using System.Threading.Tasks;
#endif
#if NET35
using Google.Protobuf.Compatibility;
#endif
namespace Google.Protobuf
{
@ -141,6 +148,55 @@ namespace Google.Protobuf
return bytes == "" ? Empty : new ByteString(Convert.FromBase64String(bytes));
}
/// <summary>
/// Constructs a <see cref="ByteString"/> from data in the given stream, synchronously.
/// </summary>
/// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
/// at the start of the call.</remarks>
/// <param name="stream">The stream to copy into a ByteString.</param>
/// <returns>A ByteString with content read from the given stream.</returns>
public static ByteString FromStream(Stream stream)
{
ProtoPreconditions.CheckNotNull(stream, nameof(stream));
int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
var memoryStream = new MemoryStream(capacity);
stream.CopyTo(memoryStream);
#if NETSTANDARD1_0
byte[] bytes = memoryStream.ToArray();
#else
// Avoid an extra copy if we can.
byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
#endif
return AttachBytes(bytes);
}
#if !NET35
/// <summary>
/// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously.
/// </summary>
/// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
/// at the start of the call.</remarks>
/// <param name="stream">The stream to copy into a ByteString.</param>
/// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param>
/// <returns>A ByteString with content read from the given stream.</returns>
public async static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
ProtoPreconditions.CheckNotNull(stream, nameof(stream));
int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
var memoryStream = new MemoryStream(capacity);
// We have to specify the buffer size here, as there's no overload accepting the cancellation token
// alone. But it's documented to use 81920 by default if not specified.
await stream.CopyToAsync(memoryStream, 81920, cancellationToken);
#if NETSTANDARD1_0
byte[] bytes = memoryStream.ToArray();
#else
// Avoid an extra copy if we can.
byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
#endif
return AttachBytes(bytes);
}
#endif
/// <summary>
/// Constructs a <see cref="ByteString" /> from the given array. The contents
/// are copied, so further modifications to the array will not

View file

@ -715,7 +715,7 @@ namespace Google.Protobuf.Collections
{
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
}
if (arrayIndex + Count >= array.Length)
if (arrayIndex + Count > array.Length)
{
throw new ArgumentException("Not enough space in the array", nameof(array));
}
@ -746,7 +746,7 @@ namespace Google.Protobuf.Collections
{
throw new ArgumentOutOfRangeException(nameof(index));
}
if (index + Count >= array.Length)
if (index + Count > array.Length)
{
throw new ArgumentException("Not enough space in the array", nameof(array));
}

View file

@ -47,6 +47,9 @@ namespace Google.Protobuf.Collections
/// </remarks>
/// <typeparam name="T">The element type of the repeated field.</typeparam>
public sealed class RepeatedField<T> : IList<T>, IList, IDeepCloneable<RepeatedField<T>>, IEquatable<RepeatedField<T>>
#if !NET35
, IReadOnlyList<T>
#endif
{
private static readonly T[] EmptyArray = new T[0];
private const int MinArraySize = 8;

View file

@ -47,7 +47,7 @@ namespace Google.Protobuf.Compatibility
/// </summary>
internal static MethodInfo GetGetMethod(this PropertyInfo target)
{
#if DOTNET35
#if NET35
var method = target.GetGetMethod();
#else
var method = target.GetMethod;
@ -61,7 +61,7 @@ namespace Google.Protobuf.Compatibility
/// </summary>
internal static MethodInfo GetSetMethod(this PropertyInfo target)
{
#if DOTNET35
#if NET35
var method = target.GetSetMethod();
#else
var method = target.SetMethod;

View file

@ -0,0 +1,66 @@
#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
#if NET35
using System;
using System.IO;
namespace Google.Protobuf.Compatibility
{
/// <summary>
/// Extension methods for <see cref="Stream"/> in order to provide
/// backwards compatibility with .NET 3.5
/// </summary>
public static class StreamExtensions
{
// 81920 seems to be the default buffer size used in .NET 4.5.1
private const int BUFFER_SIZE = 81920;
/// <summary>
/// Write the contents of the current stream to the destination stream
/// </summary>
public static void CopyTo(this Stream source, Stream destination)
{
if (destination == null)
{
throw new ArgumentNullException(nameof(destination));
}
byte[] buffer = new byte[BUFFER_SIZE];
int numBytesRead;
while ((numBytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {
destination.Write(buffer, 0, numBytesRead);
}
}
}
}
#endif

View file

@ -33,7 +33,7 @@
using System;
using System.Reflection;
#if !DOTNET35
#if !NET35
namespace Google.Protobuf.Compatibility
{
/// <summary>

63
csharp/src/Google.Protobuf/JsonFormatter.cs Normal file → Executable file
View file

@ -375,14 +375,21 @@ namespace Google.Protobuf
}
else if (value is System.Enum)
{
string name = OriginalEnumValueHelper.GetOriginalName(value);
if (name != null)
if (settings.FormatEnumsAsIntegers)
{
WriteString(writer, name);
WriteValue(writer, (int)value);
}
else
{
WriteValue(writer, (int)value);
string name = OriginalEnumValueHelper.GetOriginalName(value);
if (name != null)
{
WriteString(writer, name);
}
else
{
WriteValue(writer, (int)value);
}
}
}
else if (value is float || value is double)
@ -778,7 +785,11 @@ namespace Google.Protobuf
/// </summary>
public TypeRegistry TypeRegistry { get; }
// TODO: Work out how we're going to scale this to multiple settings. "WithXyz" methods?
/// <summary>
/// Whether to format enums as ints. Defaults to false.
/// </summary>
public bool FormatEnumsAsIntegers { get; }
/// <summary>
/// Creates a new <see cref="Settings"/> object with the specified formatting of default values
@ -795,11 +806,42 @@ namespace Google.Protobuf
/// </summary>
/// <param name="formatDefaultValues"><c>true</c> if default values (0, empty strings etc) should be formatted; <c>false</c> otherwise.</param>
/// <param name="typeRegistry">The <see cref="TypeRegistry"/> to use when formatting <see cref="Any"/> messages.</param>
public Settings(bool formatDefaultValues, TypeRegistry typeRegistry)
public Settings(bool formatDefaultValues, TypeRegistry typeRegistry) : this(formatDefaultValues, typeRegistry, false)
{
}
/// <summary>
/// Creates a new <see cref="Settings"/> object with the specified parameters.
/// </summary>
/// <param name="formatDefaultValues"><c>true</c> if default values (0, empty strings etc) should be formatted; <c>false</c> otherwise.</param>
/// <param name="typeRegistry">The <see cref="TypeRegistry"/> to use when formatting <see cref="Any"/> messages. TypeRegistry.Empty will be used if it is null.</param>
/// <param name="formatEnumsAsIntegers"><c>true</c> to format the enums as integers; <c>false</c> to format enums as enum names.</param>
private Settings(bool formatDefaultValues,
TypeRegistry typeRegistry,
bool formatEnumsAsIntegers)
{
FormatDefaultValues = formatDefaultValues;
TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
TypeRegistry = typeRegistry ?? TypeRegistry.Empty;
FormatEnumsAsIntegers = formatEnumsAsIntegers;
}
/// <summary>
/// Creates a new <see cref="Settings"/> object with the specified formatting of default values and the current settings.
/// </summary>
/// <param name="formatDefaultValues"><c>true</c> if default values (0, empty strings etc) should be formatted; <c>false</c> otherwise.</param>
public Settings WithFormatDefaultValues(bool formatDefaultValues) => new Settings(formatDefaultValues, TypeRegistry, FormatEnumsAsIntegers);
/// <summary>
/// Creates a new <see cref="Settings"/> object with the specified type registry and the current settings.
/// </summary>
/// <param name="typeRegistry">The <see cref="TypeRegistry"/> to use when formatting <see cref="Any"/> messages.</param>
public Settings WithTypeRegistry(TypeRegistry typeRegistry) => new Settings(FormatDefaultValues, typeRegistry, FormatEnumsAsIntegers);
/// <summary>
/// Creates a new <see cref="Settings"/> object with the specified enums formatting option and the current settings.
/// </summary>
/// <param name="formatEnumsAsIntegers"><c>true</c> to format the enums as integers; <c>false</c> to format enums as enum names.</param>
public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) => new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers);
}
// Effectively a cache of mapping from enum values to the original name as specified in the proto file,
@ -831,10 +873,13 @@ namespace Google.Protobuf
return originalName;
}
#if DOTNET35
#if NET35
// TODO: Consider adding functionality to TypeExtensions to avoid this difference.
private static Dictionary<object, string> GetNameMapping(System.Type enumType) =>
enumType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
.Where(f => (f.GetCustomAttributes(typeof(OriginalNameAttribute), false)
.FirstOrDefault() as OriginalNameAttribute)
?.PreferredAlias ?? true)
.ToDictionary(f => f.GetValue(null),
f => (f.GetCustomAttributes(typeof(OriginalNameAttribute), false)
.FirstOrDefault() as OriginalNameAttribute)
@ -844,6 +889,8 @@ namespace Google.Protobuf
private static Dictionary<object, string> GetNameMapping(System.Type enumType) =>
enumType.GetTypeInfo().DeclaredFields
.Where(f => f.IsStatic)
.Where(f => f.GetCustomAttributes<OriginalNameAttribute>()
.FirstOrDefault()?.PreferredAlias ?? true)
.ToDictionary(f => f.GetValue(null),
f => f.GetCustomAttributes<OriginalNameAttribute>()
.FirstOrDefault()

View file

@ -0,0 +1,390 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2017 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 System;
using System.Collections.Generic;
namespace Google.Protobuf.Reflection
{
/// <summary>
/// Container for a set of custom options specified within a message, field etc.
/// </summary>
/// <remarks>
/// <para>
/// This type is publicly immutable, but internally mutable. It is only populated
/// by the descriptor parsing code - by the time any user code is able to see an instance,
/// it will be fully initialized.
/// </para>
/// <para>
/// If an option is requested using the incorrect method, an answer may still be returned: all
/// of the numeric types are represented internally using 64-bit integers, for example. It is up to
/// the caller to ensure that they make the appropriate method call for the option they're interested in.
/// Note that enum options are simply stored as integers, so the value should be fetched using
/// <see cref="TryGetInt32(int, out int)"/> and then cast appropriately.
/// </para>
/// <para>
/// Repeated options are currently not supported. Asking for a single value of an option
/// which was actually repeated will return the last value, except for message types where
/// all the set values are merged together.
/// </para>
/// </remarks>
public sealed class CustomOptions
{
/// <summary>
/// Singleton for all descriptors with an empty set of options.
/// </summary>
internal static readonly CustomOptions Empty = new CustomOptions();
/// <summary>
/// A sequence of values per field. This needs to be per field rather than per tag to allow correct deserialization
/// of repeated fields which could be "int, ByteString, int" - unlikely as that is. The fact that values are boxed
/// is unfortunate; we might be able to use a struct instead, and we could combine uint and ulong values.
/// </summary>
private readonly Dictionary<int, List<FieldValue>> valuesByField = new Dictionary<int, List<FieldValue>>();
private CustomOptions() { }
/// <summary>
/// Retrieves a Boolean value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetBool(int field, out bool value)
{
ulong? tmp = GetLastNumericValue(field);
value = tmp == 1UL;
return tmp != null;
}
/// <summary>
/// Retrieves a signed 32-bit integer value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetInt32(int field, out int value)
{
ulong? tmp = GetLastNumericValue(field);
value = (int) tmp.GetValueOrDefault();
return tmp != null;
}
/// <summary>
/// Retrieves a signed 64-bit integer value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetInt64(int field, out long value)
{
ulong? tmp = GetLastNumericValue(field);
value = (long) tmp.GetValueOrDefault();
return tmp != null;
}
/// <summary>
/// Retrieves an unsigned 32-bit integer value for the specified option field,
/// assuming a fixed-length representation.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetFixed32(int field, out uint value) => TryGetUInt32(field, out value);
/// <summary>
/// Retrieves an unsigned 64-bit integer value for the specified option field,
/// assuming a fixed-length representation.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetFixed64(int field, out ulong value) => TryGetUInt64(field, out value);
/// <summary>
/// Retrieves a signed 32-bit integer value for the specified option field,
/// assuming a fixed-length representation.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetSFixed32(int field, out int value) => TryGetInt32(field, out value);
/// <summary>
/// Retrieves a signed 64-bit integer value for the specified option field,
/// assuming a fixed-length representation.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetSFixed64(int field, out long value) => TryGetInt64(field, out value);
/// <summary>
/// Retrieves a signed 32-bit integer value for the specified option field,
/// assuming a zigzag encoding.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetSInt32(int field, out int value)
{
ulong? tmp = GetLastNumericValue(field);
value = CodedInputStream.DecodeZigZag32((uint) tmp.GetValueOrDefault());
return tmp != null;
}
/// <summary>
/// Retrieves a signed 64-bit integer value for the specified option field,
/// assuming a zigzag encoding.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetSInt64(int field, out long value)
{
ulong? tmp = GetLastNumericValue(field);
value = CodedInputStream.DecodeZigZag64(tmp.GetValueOrDefault());
return tmp != null;
}
/// <summary>
/// Retrieves an unsigned 32-bit integer value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetUInt32(int field, out uint value)
{
ulong? tmp = GetLastNumericValue(field);
value = (uint) tmp.GetValueOrDefault();
return tmp != null;
}
/// <summary>
/// Retrieves an unsigned 64-bit integer value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetUInt64(int field, out ulong value)
{
ulong? tmp = GetLastNumericValue(field);
value = tmp.GetValueOrDefault();
return tmp != null;
}
/// <summary>
/// Retrieves a 32-bit floating point value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetFloat(int field, out float value)
{
ulong? tmp = GetLastNumericValue(field);
int int32 = (int) tmp.GetValueOrDefault();
byte[] bytes = BitConverter.GetBytes(int32);
value = BitConverter.ToSingle(bytes, 0);
return tmp != null;
}
/// <summary>
/// Retrieves a 64-bit floating point value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetDouble(int field, out double value)
{
ulong? tmp = GetLastNumericValue(field);
value = BitConverter.Int64BitsToDouble((long) tmp.GetValueOrDefault());
return tmp != null;
}
/// <summary>
/// Retrieves a string value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetString(int field, out string value)
{
ByteString bytes = GetLastByteStringValue(field);
value = bytes?.ToStringUtf8();
return bytes != null;
}
/// <summary>
/// Retrieves a bytes value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetBytes(int field, out ByteString value)
{
ByteString bytes = GetLastByteStringValue(field);
value = bytes;
return bytes != null;
}
/// <summary>
/// Retrieves a message value for the specified option field.
/// </summary>
/// <param name="field">The field to fetch the value for.</param>
/// <param name="value">The output variable to populate.</param>
/// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
public bool TryGetMessage<T>(int field, out T value) where T : class, IMessage, new()
{
value = null;
List<FieldValue> values;
if (!valuesByField.TryGetValue(field, out values))
{
return false;
}
foreach (FieldValue fieldValue in values)
{
if (fieldValue.ByteString != null)
{
if (value == null)
{
value = new T();
}
value.MergeFrom(fieldValue.ByteString);
}
}
return value != null;
}
private ulong? GetLastNumericValue(int field)
{
List<FieldValue> values;
if (!valuesByField.TryGetValue(field, out values))
{
return null;
}
for (int i = values.Count - 1; i >= 0; i--)
{
// A non-bytestring value is a numeric value
if (values[i].ByteString == null)
{
return values[i].Number;
}
}
return null;
}
private ByteString GetLastByteStringValue(int field)
{
List<FieldValue> values;
if (!valuesByField.TryGetValue(field, out values))
{
return null;
}
for (int i = values.Count - 1; i >= 0; i--)
{
if (values[i].ByteString != null)
{
return values[i].ByteString;
}
}
return null;
}
/// <summary>
/// Reads an unknown field, either parsing it and storing it or skipping it.
/// </summary>
/// <remarks>
/// If the current set of options is empty and we manage to read a field, a new set of options
/// will be created and returned. Otherwise, the return value is <c>this</c>. This allows
/// us to start with a singleton empty set of options and just create new ones where necessary.
/// </remarks>
/// <param name="input">Input stream to read from. </param>
/// <returns>The resulting set of custom options, either <c>this</c> or a new set.</returns>
internal CustomOptions ReadOrSkipUnknownField(CodedInputStream input)
{
var tag = input.LastTag;
var field = WireFormat.GetTagFieldNumber(tag);
switch (WireFormat.GetTagWireType(tag))
{
case WireFormat.WireType.LengthDelimited:
return AddValue(field, new FieldValue(input.ReadBytes()));
case WireFormat.WireType.Fixed32:
return AddValue(field, new FieldValue(input.ReadFixed32()));
case WireFormat.WireType.Fixed64:
return AddValue(field, new FieldValue(input.ReadFixed64()));
case WireFormat.WireType.Varint:
return AddValue(field, new FieldValue(input.ReadRawVarint64()));
// For StartGroup, EndGroup or any wire format we don't understand,
// just use the normal behavior (call SkipLastField).
default:
input.SkipLastField();
return this;
}
}
private CustomOptions AddValue(int field, FieldValue value)
{
var ret = valuesByField.Count == 0 ? new CustomOptions() : this;
List<FieldValue> valuesForField;
if (!ret.valuesByField.TryGetValue(field, out valuesForField))
{
// Expect almost all
valuesForField = new List<FieldValue>(1);
ret.valuesByField[field] = valuesForField;
}
valuesForField.Add(value);
return ret;
}
/// <summary>
/// All field values can be stored as a byte string or a 64-bit integer.
/// This struct avoids unnecessary boxing.
/// </summary>
private struct FieldValue
{
internal ulong Number { get; }
internal ByteString ByteString { get; }
internal FieldValue(ulong number)
{
Number = number;
ByteString = null;
}
internal FieldValue(ByteString byteString)
{
Number = 0;
ByteString = byteString;
}
}
}
}

View file

@ -80,7 +80,7 @@ namespace Google.Protobuf.Reflection {
"ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n",
"b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt",
"aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm",
"YWxzZSKaBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
"YWxzZSK0BQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
"FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf",
"ZmlsZXMYCiABKAg6BWZhbHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu",
"ZF9oYXNoGBQgASgIQgIYARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg",
@ -91,61 +91,62 @@ namespace Google.Protobuf.Reflection {
"cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
"ZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFs",
"c2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVz",
"cGFjZRglIAEoCRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSQwoUdW5pbnRlcnBy",
"ZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJw",
"cmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAESDQoJQ09E",
"RV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAkoECCYQJyLs",
"AQoOTWVzc2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQY",
"ASABKAg6BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNz",
"b3IYAiABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhEK",
"CW1hcF9lbnRyeRgHIAEoCBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByAD",
"KAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgH",
"EICAgIACSgQICBAJIp4DCgxGaWVsZE9wdGlvbnMSOgoFY3R5cGUYASABKA4y",
"Iy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkcS",
"DgoGcGFja2VkGAIgASgIEj8KBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90",
"b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUwSEwoEbGF6eRgF",
"IAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEwoEd2Vh",
"axgKIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygL",
"MiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iLwoFQ1R5",
"cGUSCgoGU1RSSU5HEAASCAoEQ09SRBABEhAKDFNUUklOR19QSUVDRRACIjUK",
"BkpTVHlwZRINCglKU19OT1JNQUwQABINCglKU19TVFJJTkcQARINCglKU19O",
"VU1CRVIQAioJCOgHEICAgIACSgQIBBAFIl4KDE9uZW9mT3B0aW9ucxJDChR1",
"bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYu",
"VW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIo0BCgtFbnVtT3B0aW9u",
"cxITCgthbGxvd19hbGlhcxgCIAEoCBIZCgpkZXByZWNhdGVkGAMgASgIOgVm",
"YWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUu",
"cHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIn0KEEVu",
"dW1WYWx1ZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2USQwoU",
"dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm",
"LlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiJ7Cg5TZXJ2aWNlT3B0",
"aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJl",
"dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
"ZXRlZE9wdGlvbioJCOgHEICAgIACIq0CCg1NZXRob2RPcHRpb25zEhkKCmRl",
"cHJlY2F0ZWQYISABKAg6BWZhbHNlEl8KEWlkZW1wb3RlbmN5X2xldmVsGCIg",
"ASgOMi8uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVu",
"Y3lMZXZlbDoTSURFTVBPVEVOQ1lfVU5LTk9XThJDChR1bmludGVycHJldGVk",
"X29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRl",
"ZE9wdGlvbiJQChBJZGVtcG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VO",
"S05PV04QABITCg9OT19TSURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIq",
"CQjoBxCAgICAAiKeAgoTVW5pbnRlcnByZXRlZE9wdGlvbhI7CgRuYW1lGAIg",
"AygLMi0uZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFt",
"ZVBhcnQSGAoQaWRlbnRpZmllcl92YWx1ZRgDIAEoCRIaChJwb3NpdGl2ZV9p",
"bnRfdmFsdWUYBCABKAQSGgoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDEhQK",
"DGRvdWJsZV92YWx1ZRgGIAEoARIUCgxzdHJpbmdfdmFsdWUYByABKAwSFwoP",
"YWdncmVnYXRlX3ZhbHVlGAggASgJGjMKCE5hbWVQYXJ0EhEKCW5hbWVfcGFy",
"dBgBIAIoCRIUCgxpc19leHRlbnNpb24YAiACKAgi1QEKDlNvdXJjZUNvZGVJ",
"bmZvEjoKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnByb3RvYnVmLlNvdXJj",
"ZUNvZGVJbmZvLkxvY2F0aW9uGoYBCghMb2NhdGlvbhIQCgRwYXRoGAEgAygF",
"QgIQARIQCgRzcGFuGAIgAygFQgIQARIYChBsZWFkaW5nX2NvbW1lbnRzGAMg",
"ASgJEhkKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJEiEKGWxlYWRpbmdfZGV0",
"YWNoZWRfY29tbWVudHMYBiADKAkipwEKEUdlbmVyYXRlZENvZGVJbmZvEkEK",
"CmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVk",
"Q29kZUluZm8uQW5ub3RhdGlvbhpPCgpBbm5vdGF0aW9uEhAKBHBhdGgYASAD",
"KAVCAhABEhMKC3NvdXJjZV9maWxlGAIgASgJEg0KBWJlZ2luGAMgASgFEgsK",
"A2VuZBgEIAEoBUKMAQoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRv",
"clByb3Rvc0gBWj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90b2Mt",
"Z2VuLWdvL2Rlc2NyaXB0b3I7ZGVzY3JpcHRvcqICA0dQQqoCGkdvb2dsZS5Q",
"cm90b2J1Zi5SZWZsZWN0aW9u"));
"cGFjZRglIAEoCRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSGAoQcGhwX2NsYXNz",
"X3ByZWZpeBgoIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy",
"JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRp",
"bWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JV",
"TlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIvIBCg5NZXNzYWdlT3B0aW9ucxIm",
"ChdtZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9f",
"c3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoK",
"ZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMK",
"FHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1",
"Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgIEAlKBAgJEAoi",
"ngMKDEZpZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90",
"b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiAB",
"KAgSPwoGanN0eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0",
"aW9ucy5KU1R5cGU6CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZ",
"CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxz",
"ZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJv",
"dG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQ",
"ABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpT",
"X05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQ",
"gICAgAJKBAgEEAUiXgoMT25lb2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRf",
"b3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVk",
"T3B0aW9uKgkI6AcQgICAgAIikwEKC0VudW1PcHRpb25zEhMKC2FsbG93X2Fs",
"aWFzGAIgASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50",
"ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
"dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYifQoQRW51bVZhbHVl",
"T3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVy",
"cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl",
"cnByZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkK",
"CmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0",
"aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0",
"aW9uKgkI6AcQgICAgAIirQIKDU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRl",
"ZBghIAEoCDoFZmFsc2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5n",
"b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90ZW5jeUxldmVs",
"OhNJREVNUE9URU5DWV9VTktOT1dOEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u",
"GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
"IlAKEElkZW1wb3RlbmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAA",
"EhMKD05PX1NJREVfRUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICA",
"gIACIp4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5n",
"b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIY",
"ChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1",
"ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91Ymxl",
"X3ZhbHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdh",
"dGVfdmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJ",
"EhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoI",
"bG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUlu",
"Zm8uTG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAK",
"BHNwYW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoR",
"dHJhaWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9j",
"b21tZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3Rh",
"dGlvbhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5m",
"by5Bbm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAES",
"EwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQg",
"ASgFQowBChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9z",
"SAFaPmdpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvYy1nZW4tZ28v",
"ZGVzY3JpcHRvcjtkZXNjcmlwdG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVm",
"LlJlZmxlY3Rpb24="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@ -159,7 +160,7 @@ namespace Google.Protobuf.Reflection {
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null),
@ -2782,6 +2783,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileOptions() {
OnConstruction();
@ -2806,6 +2809,7 @@ namespace Google.Protobuf.Reflection {
objcClassPrefix_ = other.objcClassPrefix_;
csharpNamespace_ = other.csharpNamespace_;
swiftPrefix_ = other.swiftPrefix_;
phpClassPrefix_ = other.phpClassPrefix_;
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
@ -3054,6 +3058,21 @@ namespace Google.Protobuf.Reflection {
}
}
/// <summary>Field number for the "php_class_prefix" field.</summary>
public const int PhpClassPrefixFieldNumber = 40;
private string phpClassPrefix_ = "";
/// <summary>
/// Sets the php class prefix which is prepended to all php generated classes
/// from this .proto. Default is empty.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string PhpClassPrefix {
get { return phpClassPrefix_; }
set {
phpClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "uninterpreted_option" field.</summary>
public const int UninterpretedOptionFieldNumber = 999;
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
@ -3095,6 +3114,7 @@ namespace Google.Protobuf.Reflection {
if (ObjcClassPrefix != other.ObjcClassPrefix) return false;
if (CsharpNamespace != other.CsharpNamespace) return false;
if (SwiftPrefix != other.SwiftPrefix) return false;
if (PhpClassPrefix != other.PhpClassPrefix) return false;
if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
return true;
}
@ -3117,6 +3137,7 @@ namespace Google.Protobuf.Reflection {
if (ObjcClassPrefix.Length != 0) hash ^= ObjcClassPrefix.GetHashCode();
if (CsharpNamespace.Length != 0) hash ^= CsharpNamespace.GetHashCode();
if (SwiftPrefix.Length != 0) hash ^= SwiftPrefix.GetHashCode();
if (PhpClassPrefix.Length != 0) hash ^= PhpClassPrefix.GetHashCode();
hash ^= uninterpretedOption_.GetHashCode();
return hash;
}
@ -3188,6 +3209,10 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(186, 2);
output.WriteString(SwiftPrefix);
}
if (PhpClassPrefix.Length != 0) {
output.WriteRawTag(194, 2);
output.WriteString(PhpClassPrefix);
}
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
@ -3239,6 +3264,9 @@ namespace Google.Protobuf.Reflection {
if (SwiftPrefix.Length != 0) {
size += 2 + pb::CodedOutputStream.ComputeStringSize(SwiftPrefix);
}
if (PhpClassPrefix.Length != 0) {
size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpClassPrefix);
}
size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
return size;
}
@ -3293,6 +3321,9 @@ namespace Google.Protobuf.Reflection {
if (other.SwiftPrefix.Length != 0) {
SwiftPrefix = other.SwiftPrefix;
}
if (other.PhpClassPrefix.Length != 0) {
PhpClassPrefix = other.PhpClassPrefix;
}
uninterpretedOption_.Add(other.uninterpretedOption_);
}
@ -3302,7 +3333,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 10: {
JavaPackage = input.ReadString();
@ -3364,6 +3395,10 @@ namespace Google.Protobuf.Reflection {
SwiftPrefix = input.ReadString();
break;
}
case 322: {
PhpClassPrefix = input.ReadString();
break;
}
case 7994: {
uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
break;
@ -3414,6 +3449,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageOptions() {
OnConstruction();
@ -3649,7 +3686,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 8: {
MessageSetWireFormat = input.ReadBool();
@ -3692,6 +3729,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldOptions() {
OnConstruction();
@ -3983,7 +4022,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 8: {
ctype_ = (global::Google.Protobuf.Reflection.FieldOptions.Types.CType) input.ReadEnum();
@ -4065,6 +4104,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofOptions() {
OnConstruction();
@ -4150,7 +4191,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 7994: {
uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
@ -4177,6 +4218,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumOptions() {
OnConstruction();
@ -4320,7 +4363,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 16: {
AllowAlias = input.ReadBool();
@ -4355,6 +4398,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValueOptions() {
OnConstruction();
@ -4470,7 +4515,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 8: {
Deprecated = input.ReadBool();
@ -4501,6 +4546,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceOptions() {
OnConstruction();
@ -4616,7 +4663,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 264: {
Deprecated = input.ReadBool();
@ -4647,6 +4694,8 @@ namespace Google.Protobuf.Reflection {
get { return Descriptor; }
}
internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MethodOptions() {
OnConstruction();
@ -4786,7 +4835,7 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
break;
case 264: {
Deprecated = input.ReadBool();

View file

@ -112,5 +112,10 @@ namespace Google.Protobuf.Reflection
{
return File.DescriptorPool.FindSymbol<EnumValueDescriptor>(FullName + "." + name);
}
/// <summary>
/// The (possibly empty) set of custom options for this enum.
/// </summary>
public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
}
}

View file

@ -66,5 +66,10 @@ namespace Google.Protobuf.Reflection
/// Returns the enum descriptor that this value is part of.
/// </summary>
public EnumDescriptor EnumDescriptor { get { return enumDescriptor; } }
/// <summary>
/// The (possibly empty) set of custom options for this enum value.
/// </summary>
public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
}
}

View file

@ -250,6 +250,11 @@ namespace Google.Protobuf.Reflection
}
}
/// <summary>
/// The (possibly empty) set of custom options for this field.
/// </summary>
public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
/// <summary>
/// Look up and cross-link all field types etc.
/// </summary>

View file

@ -329,5 +329,10 @@ namespace Google.Protobuf.Reflection
/// The file descriptor for <c>descriptor.proto</c>.
/// </value>
public static FileDescriptor DescriptorProtoFileDescriptor { get { return DescriptorReflection.Descriptor; } }
/// <summary>
/// The (possibly empty) set of custom options for this file.
/// </summary>
public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
}
}

View file

@ -34,7 +34,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
#if DOTNET35
#if NET35
// Needed for ReadOnlyDictionary, which does not exist in .NET 3.5
using Google.Protobuf.Collections;
#endif
@ -220,6 +220,11 @@ namespace Google.Protobuf.Reflection
public T FindDescriptor<T>(string name) where T : class, IDescriptor =>
File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
/// <summary>
/// The (possibly empty) set of custom options for this message.
/// </summary>
public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
/// <summary>
/// Looks up and cross-links all fields and nested types.
/// </summary>

View file

@ -67,6 +67,11 @@ namespace Google.Protobuf.Reflection
/// </value>
public bool IsServerStreaming { get { return proto.ServerStreaming; } }
/// <summary>
/// The (possibly empty) set of custom options for this method.
/// </summary>
public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
internal MethodDescriptor(MethodDescriptorProto proto, FileDescriptor file,
ServiceDescriptor parent, int index)
: base(file, parent.FullName + "." + proto.Name, index)

View file

@ -90,6 +90,11 @@ namespace Google.Protobuf.Reflection
/// </value>
public OneofAccessor Accessor { get { return accessor; } }
/// <summary>
/// The (possibly empty) set of custom options for this oneof.
/// </summary>
public CustomOptions CustomOptions => proto.Options?.CustomOptions ?? CustomOptions.Empty;
internal void CrossLink()
{
List<FieldDescriptor> fieldCollection = new List<FieldDescriptor>();

View file

@ -46,6 +46,11 @@ namespace Google.Protobuf.Reflection
/// </summary>
public string Name { get; set; }
/// <summary>
/// If the name is preferred in the .proto file.
/// </summary>
public bool PreferredAlias { get; set; }
/// <summary>
/// Constructs a new attribute instance for the given name.
/// </summary>
@ -53,6 +58,8 @@ namespace Google.Protobuf.Reflection
public OriginalNameAttribute(string name)
{
Name = ProtoPreconditions.CheckNotNull(name, nameof(name));
PreferredAlias = true;
}
}
}
}

View file

@ -78,6 +78,11 @@ namespace Google.Protobuf.Reflection
return File.DescriptorPool.FindSymbol<MethodDescriptor>(FullName + "." + name);
}
/// <summary>
/// The (possibly empty) set of custom options for this service.
/// </summary>
public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
internal void CrossLink()
{
foreach (MethodDescriptor method in methods)

View file

@ -46,6 +46,8 @@ namespace Google.Protobuf.WellKnownTypes {
/// two Timestamp values is a Duration and it can be added or subtracted
/// from a Timestamp. Range is approximately +-10,000 years.
///
/// # Examples
///
/// Example 1: Compute Duration from two Timestamps in pseudo code.
///
/// Timestamp start = ...;
@ -85,6 +87,16 @@ namespace Google.Protobuf.WellKnownTypes {
/// td = datetime.timedelta(days=3, minutes=10)
/// duration = Duration()
/// duration.FromTimedelta(td)
///
/// # JSON Mapping
///
/// In JSON format, the Duration type is encoded as a string rather than an
/// object, where the string ends in the suffix "s" (indicating seconds) and
/// is preceded by the number of seconds, with nanoseconds expressed as
/// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
/// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
/// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
/// microsecond should be expressed in JSON format as "3.000001s".
/// </summary>
public sealed partial class Duration : pb::IMessage<Duration> {
private static readonly pb::MessageParser<Duration> _parser = new pb::MessageParser<Duration>(() => new Duration());
@ -124,7 +136,8 @@ namespace Google.Protobuf.WellKnownTypes {
private long seconds_;
/// <summary>
/// Signed seconds of the span of time. Must be from -315,576,000,000
/// to +315,576,000,000 inclusive.
/// to +315,576,000,000 inclusive. Note: these bounds are computed from:
/// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long Seconds {

View file

@ -59,7 +59,7 @@ namespace Google.Protobuf.WellKnownTypes
if (firstInvalid == null)
{
var writer = new StringWriter();
#if DOTNET35
#if NET35
var query = paths.Select(JsonFormatter.ToJsonName);
JsonFormatter.WriteString(writer, string.Join(",", query.ToArray()));
#else

View file

@ -51,6 +51,8 @@ namespace Google.Protobuf.WellKnownTypes {
/// and from RFC 3339 date strings.
/// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
///
/// # Examples
///
/// Example 1: Compute Timestamp from POSIX `time()`.
///
/// Timestamp timestamp;
@ -89,6 +91,29 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// timestamp = Timestamp()
/// timestamp.GetCurrentTime()
///
/// # JSON Mapping
///
/// In JSON format, the Timestamp type is encoded as a string in the
/// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
/// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
/// where {year} is always expressed using four digits while {month}, {day},
/// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
/// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
/// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
/// is required, though only UTC (as indicated by "Z") is presently supported.
///
/// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
/// 01:30 UTC on January 15, 2017.
///
/// In JavaScript, one can convert a Date object to this format using the
/// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
/// method. In Python, a standard `datetime.datetime` object can be converted
/// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
/// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
/// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
/// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime())
/// to obtain a formatter capable of generating timestamps in this format.
/// </summary>
public sealed partial class Timestamp : pb::IMessage<Timestamp> {
private static readonly pb::MessageParser<Timestamp> _parser = new pb::MessageParser<Timestamp>(() => new Timestamp());

View file

@ -1,5 +1,5 @@
{
"version": "3.2.0",
"version": "3.3.0",
"title": "Google Protocol Buffers",
"description": "See project site for more info.",
"authors": [ "Google Inc." ],

Some files were not shown because too many files have changed in this diff Show more