aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt20
-rw-r--r--INSTALL.txt237
-rw-r--r--Makefile.am1
-rw-r--r--README.md35
-rw-r--r--cmake/README.md6
-rw-r--r--conformance/Makefile.am27
-rw-r--r--conformance/conformance_test.cc8
-rw-r--r--conformance/conformance_test_runner.cc64
-rw-r--r--conformance/failure_list_cpp.txt3
-rw-r--r--conformance/failure_list_csharp.txt89
-rw-r--r--conformance/failure_list_java.txt25
-rw-r--r--conformance/failure_list_python-post26.txt2
-rw-r--r--conformance/failure_list_python.txt173
-rw-r--r--conformance/failure_list_python_cpp.txt173
-rw-r--r--conformance/failure_list_ruby.txt335
-rw-r--r--csharp/CHANGES.txt2
-rw-r--r--csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs56
-rw-r--r--csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs36
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs48
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonParserTest.cs72
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs18
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs11
-rw-r--r--csharp/src/Google.Protobuf/Collections/MapField.cs53
-rw-r--r--csharp/src/Google.Protobuf/FieldCodec.cs5
-rw-r--r--csharp/src/Google.Protobuf/JsonFormatter.cs52
-rw-r--r--csharp/src/Google.Protobuf/JsonParser.cs95
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Any.cs6
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Api.cs1
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs6
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs2
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs6
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Type.cs132
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs7
-rw-r--r--m4/stl_hash.m43
-rw-r--r--objectivec/GPBMessage.m1
-rw-r--r--objectivec/README.md2
-rw-r--r--protoc-artifacts/README.md4
-rwxr-xr-xpython/setup.py4
-rw-r--r--python/tox.ini6
-rwxr-xr-xruby/travis-test.sh7
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_map_field.cc3
-rw-r--r--src/google/protobuf/stubs/callback.h2
-rwxr-xr-xtravis.sh4
43 files changed, 1225 insertions, 617 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index c710cd5e..3023c812 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,6 @@
-2015-08-26 version 3.0.0-beta-1 (C++/Java/Python/Ruby/Nano/Objective-C/C#/JavaSript)
+2015-08-26 version 3.0.0-beta-1 (C++/Java/Python/Ruby/Nano/Objective-C/C#/JavaScript)
General
- * Intorduced a new language implementaion: JavaScript.
+ * Introduced a new language implementation: JavaScript.
* Added a new field option "json_name". By default proto field names are
converted to "lowerCamelCase" in proto3 JSON format. This option can be
used to override this behavior and specify a different JSON name for the
@@ -176,7 +176,7 @@
still disable packed serialization by setting packed to false for now.
* Added well-known type protos (any.proto, empty.proto, timestamp.proto,
duration.proto, etc.). Users can import and use these protos just like
- regular proto files. Addtional runtime support will be added for them in
+ regular proto files. Additional runtime support will be added for them in
future releases (in the form of utility helper functions, or having them
replaced by language specific types in generated code).
* Added a "reserved" keyword in both proto2 and proto3 syntax. User can use
@@ -218,7 +218,7 @@
https://github.com/jskeet/protobuf-csharp-port. The original project was
frozen and all the new development will happen here.
* Codegen plugin for C# was completely rewritten to C++ and is now an
- intergral part of protoc.
+ integral part of protoc.
* Some refactorings and cleanup has been applied to the C# runtime library.
* Only proto2 is supported in C# at the moment, proto3 support is in
progress and will likely bring significant breaking changes to the API.
@@ -382,7 +382,7 @@
This release (v3.0.0-alpha-1) includes partial proto3 support for C++ and
Java. Items 6 (well-known types) and 7 (JSON format) in the above feature
- list are not impelmented.
+ list are not implemented.
A new notion "syntax" is introduced to specify whether a .proto file
uses proto2 or proto3:
@@ -483,7 +483,7 @@
}
* Files, services, enums, messages, methods and enum values can be marked
as deprecated now.
- * Added Support for list values, including lists of mesaages, when
+ * Added Support for list values, including lists of messages, when
parsing text-formatted protos in C++ and Java.
For example: foo: [1, 2, 3]
@@ -563,7 +563,7 @@
Python
* Added support for dynamic message creation. DescriptorDatabase,
- DescriptorPool, and MessageFactory work like their C++ couterparts to
+ DescriptorPool, and MessageFactory work like their C++ counterparts to
simplify Descriptor construction from *DescriptorProtos, and MessageFactory
provides a message instance from a Descriptor.
* Added pickle support for protobuf messages.
@@ -577,7 +577,7 @@
2011-05-01 version 2.4.1:
C++
- * Fixed the frendship problem for old compilers to make the library now gcc 3
+ * Fixed the friendship problem for old compilers to make the library now gcc 3
compatible again.
* Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h.
@@ -844,7 +844,7 @@
* Fixed tendency for TextFormat's parsing to overflow the stack when
parsing large string values. The underlying problem is with Java's
regex implementation (which unfortunately uses recursive backtracking
- rather than building an NFA). Worked around by making use of possesive
+ rather than building an NFA). Worked around by making use of possessive
quantifiers.
* Generated service classes now also generate pure interfaces. For a service
Foo, Foo.Interface is a pure interface containing all of the service's
@@ -858,7 +858,7 @@
RPC implementations will have to implement the new interfaces in order to
support blocking mode.
* New I/O methods parseDelimitedFrom(), mergeDelimitedFrom(), and
- writeDelimitedTo() read and write "delemited" messages from/to a stream,
+ writeDelimitedTo() read and write "delimited" messages from/to a stream,
meaning that the message size precedes the data. This way, you can write
multiple messages to a stream without having to worry about delimiting
them yourself.
diff --git a/INSTALL.txt b/INSTALL.txt
deleted file mode 100644
index ce3b0949..00000000
--- a/INSTALL.txt
+++ /dev/null
@@ -1,237 +0,0 @@
-This file contains detailed but generic information on building and
-installing the C++ part of this project. For shorter instructions,
-as well as instructions for compiling and installing the Java or
-Python parts, see README.
-
-======================================================================
-
-Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
-Foundation, Inc.
-
- This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-
-Basic Installation
-==================
-
- These are generic installation instructions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. (Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.)
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You only need
-`configure.ac' if you want to change it or regenerate `configure' using
-a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system. If you're
- using `csh' on an old version of System V, you might need to type
- `sh ./configure' instead to prevent `csh' from trying to execute
- `configure' itself.
-
- Running `configure' takes awhile. While running, it prints some
- messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- If you have to use a `make' that does not support the `VPATH'
-variable, you have to compile the package for one architecture at a
-time in the source code directory. After you have installed the
-package for one architecture, use `make distclean' before reconfiguring
-for another architecture.
-
-Installation Names
-==================
-
- By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc. You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the `--target=TYPE' option to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-will cause the specified gcc to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/Makefile.am b/Makefile.am
index 49ad640c..3d39a898 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -697,7 +697,6 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
autogen.sh \
generate_descriptor_proto.sh \
README.md \
- INSTALL.txt \
LICENSE \
CONTRIBUTORS.txt \
CHANGES.txt \
diff --git a/README.md b/README.md
index a974d301..19723d36 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,20 @@ https://developers.google.com/protocol-buffers/
C++ Installation - Unix
-----------------------
+To build protobuf from source, the following tools are needed:
+
+ * autoconf
+ * automake
+ * libtool
+ * curl (used to download gmock)
+
+On Ubuntu, you can install them with:
+
+ $ sudo apt-get install autoconf automake libtool curl
+
+On other platforms, please use the corresponding package managing tool to
+install them before proceeding.
+
If you get the source from github, you need to generate the configure script
first:
@@ -28,15 +42,17 @@ Buffer compiler (protoc) execute the following:
$ ./configure
$ make
$ make check
- $ make install
+ $ sudo make install
+ $ sudo ldconfig # refresh shared library cache.
If "make check" fails, you can still install, but it is likely that
some features of this library will not work correctly on your system.
Proceed at your own risk.
-"make install" may require superuser privileges.
+For advanced usage information on configure and make, please refer to the
+autoconf documentation:
-For advanced usage information on configure and make, see INSTALL.txt.
+ http://www.gnu.org/software/autoconf/manual/autoconf.html#Running-configure-Scripts
**Hint on install location**
@@ -156,9 +172,18 @@ For advanced usage information on configure and make, see INSTALL.txt.
C++ Installation - Windows
--------------------------
-If you are using Microsoft Visual C++, see cmake/README.md.
+If you only need the protoc binary, you can download it from the release
+page:
+
+ https://github.com/google/protobuf/releases
+
+In the downloads section, download the zip file protoc-$VERSION-win32.zip.
+It contains the protoc binary as well as public proto files of protobuf
+library.
+
+To build from source using Microsoft Visual C++, see cmake/README.md.
-If you are using Cygwin or MinGW, follow the Unix installation
+To build from source using Cygwin or MinGW, follow the Unix installation
instructions, above.
Binary Compatibility Warning
diff --git a/cmake/README.md b/cmake/README.md
index b3042e6c..58aae8e9 100644
--- a/cmake/README.md
+++ b/cmake/README.md
@@ -28,11 +28,11 @@ Create a folder where protobuf headers/libraries/binaries will be installed afte
C:\Path\to>mkdir install
-If *cmake* command is not avaliable from *Command Prompt*, add it to system *PATH* variable:
+If *cmake* command is not available from *Command Prompt*, add it to system *PATH* variable:
C:\Path\to>set PATH=%PATH%;C:\Program Files (x86)\CMake\bin
-If *git* command is not avaliable from *Command Prompt*, add it to system *PATH* variable:
+If *git* command is not available from *Command Prompt*, add it to system *PATH* variable:
C:\Path\to>set PATH=%PATH%;C:\Program Files\Git\cmd
@@ -218,7 +218,7 @@ It sounds not so strange and it works.
This will create the following folders under the *install* location:
* bin - that contains protobuf *protoc.exe* compiler;
- * inclue - that contains C++ headers and protobuf *.proto files;
+ * include - that contains C++ headers and protobuf *.proto files;
* lib - that contains linking libraries and *CMake* configuration files for *protobuf* package.
Now you can if needed:
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 89d87d3e..9703101a 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -1,8 +1,17 @@
## Process this file with automake to produce Makefile.in
-protoc_inputs = \
+conformance_protoc_inputs = \
conformance.proto
+well_known_type_protoc_inputs = \
+ $(top_srcdir)/src/google/protobuf/any.proto \
+ $(top_srcdir)/src/google/protobuf/duration.proto \
+ $(top_srcdir)/src/google/protobuf/field_mask.proto \
+ $(top_srcdir)/src/google/protobuf/struct.proto \
+ $(top_srcdir)/src/google/protobuf/timestamp.proto \
+ $(top_srcdir)/src/google/protobuf/wrappers.proto
+
+
protoc_outputs = \
conformance.pb.cc \
conformance.pb.h
@@ -31,6 +40,7 @@ EXTRA_DIST = \
failure_list_objc.txt \
failure_list_python.txt \
failure_list_python_cpp.txt \
+ failure_list_python-post26.txt \
failure_list_ruby.txt
conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
@@ -74,8 +84,10 @@ endif
if USE_EXTERNAL_PROTOC
-protoc_middleman: $(protoc_inputs)
- $(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=.$^
+# 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)
touch protoc_middleman
else
@@ -83,8 +95,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) $(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 $(protoc_inputs) )
+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) )
touch protoc_middleman
endif
@@ -135,10 +148,10 @@ test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outp
# 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
- ./conformance-test-runner --failure_list failure_list_python.txt ./conformance_python.py
+ ./conformance-test-runner --failure_list failure_list_python.txt $(CONFORMANCE_PYTHON_EXTRA_FAILURES) ./conformance_python.py
test_python_cpp: protoc_middleman conformance-test-runner
- ./conformance-test-runner --failure_list failure_list_python_cpp.txt ./conformance_python.py
+ ./conformance-test-runner --failure_list failure_list_python_cpp.txt $(CONFORMANCE_PYTHON_EXTRA_FAILURES) ./conformance_python.py
if OBJC_CONFORMANCE_TEST
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index a232ecc5..fc0605bf 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -299,7 +299,13 @@ void ConformanceTestSuite::RunValidInputTest(
return;
}
- GOOGLE_CHECK(test_message.ParseFromString(binary_protobuf));
+ if (!test_message.ParseFromString(binary_protobuf)) {
+ ReportFailure(test_name, request, response,
+ "INTERNAL ERROR: internal JSON->protobuf transcode "
+ "yielded unparseable proto.");
+ return;
+ }
+
break;
}
diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc
index f2b0dabf..376a60b9 100644
--- a/conformance/conformance_test_runner.cc
+++ b/conformance/conformance_test_runner.cc
@@ -55,16 +55,21 @@
#include <algorithm>
#include <errno.h>
-#include <unistd.h>
#include <fstream>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
#include <vector>
+#include <google/protobuf/stubs/stringprintf.h>
+
#include "conformance.pb.h"
#include "conformance_test.h"
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
using google::protobuf::internal::scoped_array;
+using google::protobuf::StringAppendF;
using std::string;
using std::vector;
@@ -81,14 +86,14 @@ using std::vector;
class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
public:
ForkPipeRunner(const std::string &executable)
- : running_(false), executable_(executable) {}
+ : child_pid_(-1), executable_(executable) {}
virtual ~ForkPipeRunner() {}
void RunTest(const std::string& test_name,
const std::string& request,
std::string* response) {
- if (!running_) {
+ if (child_pid_ < 0) {
SpawnTestProgram();
}
@@ -97,7 +102,31 @@ class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
uint32_t len = request.size();
CheckedWrite(write_fd_, &len, sizeof(uint32_t));
CheckedWrite(write_fd_, request.c_str(), request.size());
- CheckedRead(read_fd_, &len, sizeof(uint32_t));
+
+ if (!TryRead(read_fd_, &len, sizeof(uint32_t))) {
+ // We failed to read from the child, assume a crash and try to reap.
+ GOOGLE_LOG(INFO) << "Trying to reap child, pid=" << child_pid_;
+
+ int status;
+ waitpid(child_pid_, &status, WEXITED);
+
+ string error_msg;
+ if (WIFEXITED(status)) {
+ StringAppendF(&error_msg,
+ "child exited, status=%d", WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ StringAppendF(&error_msg,
+ "child killed by signal %d", WTERMSIG(status));
+ }
+ GOOGLE_LOG(INFO) << error_msg;
+ child_pid_ = -1;
+
+ conformance::ConformanceResponse response_obj;
+ response_obj.set_runtime_error(error_msg);
+ response_obj.SerializeToString(response);
+ return;
+ }
+
response->resize(len);
CheckedRead(read_fd_, (void*)response->c_str(), len);
}
@@ -141,7 +170,7 @@ class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
write_fd_ = toproc_pipe_fd[1];
read_fd_ = fromproc_pipe_fd[0];
- running_ = true;
+ child_pid_ = pid;
} else {
// Child.
CHECK_SYSCALL(close(STDIN_FILENO));
@@ -171,28 +200,40 @@ class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
}
}
- void CheckedRead(int fd, void *buf, size_t len) {
+ bool TryRead(int fd, void *buf, size_t len) {
size_t ofs = 0;
while (len > 0) {
ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
if (bytes_read == 0) {
- GOOGLE_LOG(FATAL) << current_test_name_
+ GOOGLE_LOG(ERROR) << current_test_name_
<< ": unexpected EOF from test program";
+ return false;
} else if (bytes_read < 0) {
- GOOGLE_LOG(FATAL) << current_test_name_
+ GOOGLE_LOG(ERROR) << current_test_name_
<< ": error reading from test program: "
<< strerror(errno);
+ return false;
}
len -= bytes_read;
ofs += bytes_read;
}
+
+ return true;
+ }
+
+ void CheckedRead(int fd, void *buf, size_t len) {
+ if (!TryRead(fd, buf, len)) {
+ GOOGLE_LOG(FATAL) << current_test_name_
+ << ": error reading from test program: "
+ << strerror(errno);
+ }
}
int write_fd_;
int read_fd_;
- bool running_;
+ pid_t child_pid_;
std::string executable_;
std::string current_test_name_;
};
@@ -239,12 +280,12 @@ int main(int argc, char *argv[]) {
char *program;
google::protobuf::ConformanceTestSuite suite;
+ vector<string> failure_list;
+
for (int arg = 1; arg < argc; ++arg) {
if (strcmp(argv[arg], "--failure_list") == 0) {
if (++arg == argc) UsageError();
- vector<string> failure_list;
ParseFailureList(argv[arg], &failure_list);
- suite.SetFailureList(failure_list);
} else if (strcmp(argv[arg], "--verbose") == 0) {
suite.SetVerbose(true);
} else if (argv[arg][0] == '-') {
@@ -259,6 +300,7 @@ int main(int argc, char *argv[]) {
}
}
+ suite.SetFailureList(failure_list);
ForkPipeRunner runner(program);
std::string output;
diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt
index 240d4118..2ddf831c 100644
--- a/conformance/failure_list_cpp.txt
+++ b/conformance/failure_list_cpp.txt
@@ -36,9 +36,6 @@ JsonInput.FieldNameInLowerCamelCase.Validator
JsonInput.FieldNameInSnakeCase.JsonOutput
JsonInput.FieldNameInSnakeCase.ProtobufOutput
JsonInput.FieldNameNotQuoted
-JsonInput.FieldNameWithMixedCases.JsonOutput
-JsonInput.FieldNameWithMixedCases.ProtobufOutput
-JsonInput.FieldNameWithMixedCases.Validator
JsonInput.FloatFieldTooLarge
JsonInput.FloatFieldTooSmall
JsonInput.Int32FieldLeadingSpace
diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt
index e69de29b..feb17689 100644
--- a/conformance/failure_list_csharp.txt
+++ b/conformance/failure_list_csharp.txt
@@ -0,0 +1,89 @@
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AnyWithValueForInteger.JsonOutput
+JsonInput.AnyWithValueForJsonObject.JsonOutput
+JsonInput.BoolFieldAllCapitalFalse
+JsonInput.BoolFieldAllCapitalTrue
+JsonInput.BoolFieldCamelCaseFalse
+JsonInput.BoolFieldCamelCaseTrue
+JsonInput.BoolMapFieldKeyNotQuoted
+JsonInput.BytesFieldInvalidBase64Characters
+JsonInput.BytesFieldNoPadding
+JsonInput.DoubleFieldInfinityNotQuoted
+JsonInput.DoubleFieldNanNotQuoted
+JsonInput.DoubleFieldNegativeInfinityNotQuoted
+JsonInput.DoubleFieldTooLarge
+JsonInput.DoubleFieldTooSmall
+JsonInput.DurationHas3FractionalDigits.Validator
+JsonInput.DurationHas6FractionalDigits.Validator
+JsonInput.DurationHas9FractionalDigits.Validator
+JsonInput.DurationMaxValue.JsonOutput
+JsonInput.DurationMaxValue.ProtobufOutput
+JsonInput.DurationMinValue.JsonOutput
+JsonInput.DurationMinValue.ProtobufOutput
+JsonInput.EnumFieldNotQuoted
+JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+JsonInput.EnumFieldNumericValueZero.JsonOutput
+JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldNameDuplicate
+JsonInput.FieldNameDuplicateDifferentCasing2
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FieldNameNotQuoted
+JsonInput.FieldNameWithMixedCases.JsonOutput
+JsonInput.FieldNameWithMixedCases.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.Validator
+JsonInput.FloatFieldInfinityNotQuoted
+JsonInput.FloatFieldNanNotQuoted
+JsonInput.FloatFieldNegativeInfinityNotQuoted
+JsonInput.Int32FieldLeadingZero
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinValue.JsonOutput
+JsonInput.Int32FieldNegativeWithLeadingZero
+JsonInput.Int32FieldPlusSign
+JsonInput.Int32MapFieldKeyNotQuoted
+JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
+JsonInput.Int64MapFieldKeyNotQuoted
+JsonInput.JsonWithComments
+JsonInput.MapFieldKeyIsNull
+JsonInput.MapFieldValueIsNull
+JsonInput.OneofFieldDuplicate
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.OriginalProtoFieldName.ProtobufOutput
+JsonInput.RepeatedBoolWrapper.ProtobufOutput
+JsonInput.RepeatedDoubleWrapper.ProtobufOutput
+JsonInput.RepeatedFieldMessageElementIsNull
+JsonInput.RepeatedFieldPrimitiveElementIsNull
+JsonInput.RepeatedFieldTrailingComma
+JsonInput.RepeatedFloatWrapper.ProtobufOutput
+JsonInput.RepeatedInt32Wrapper.ProtobufOutput
+JsonInput.RepeatedInt64Wrapper.ProtobufOutput
+JsonInput.RepeatedUint32Wrapper.ProtobufOutput
+JsonInput.RepeatedUint64Wrapper.ProtobufOutput
+JsonInput.StringFieldInvalidEscape
+JsonInput.StringFieldSurrogateInWrongOrder
+JsonInput.StringFieldSurrogatePair.JsonOutput
+JsonInput.StringFieldUnpairedHighSurrogate
+JsonInput.StringFieldUnpairedLowSurrogate
+JsonInput.StringFieldUnterminatedEscape
+JsonInput.StringFieldUppercaseEscapeLetter
+JsonInput.TimestampHas3FractionalDigits.Validator
+JsonInput.TimestampHas6FractionalDigits.Validator
+JsonInput.TimestampHas9FractionalDigits.Validator
+JsonInput.TrailingCommaInAnObject
+JsonInput.Uint32MapFieldKeyNotQuoted
+JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
+JsonInput.Uint64MapFieldKeyNotQuoted
+JsonInput.ValueAcceptNull.JsonOutput
+JsonInput.ValueAcceptNull.ProtobufOutput
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt
index 86af18b9..552c0cc9 100644
--- a/conformance/failure_list_java.txt
+++ b/conformance/failure_list_java.txt
@@ -17,48 +17,27 @@ JsonInput.BoolFieldCamelCaseTrue
JsonInput.BoolFieldDoubleQuotedFalse
JsonInput.BoolFieldDoubleQuotedTrue
JsonInput.BoolMapFieldKeyNotQuoted
-JsonInput.BytesFieldNoPadding
JsonInput.DoubleFieldInfinityNotQuoted
JsonInput.DoubleFieldNanNotQuoted
JsonInput.DoubleFieldNegativeInfinityNotQuoted
JsonInput.EnumFieldNotQuoted
-JsonInput.EnumFieldNumericValueNonZero.JsonOutput
-JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
-JsonInput.EnumFieldNumericValueZero.JsonOutput
-JsonInput.EnumFieldNumericValueZero.ProtobufOutput
-JsonInput.EnumFieldUnknownValue.Validator
JsonInput.FieldMask.ProtobufOutput
JsonInput.FieldMaskInvalidCharacter
JsonInput.FieldNameDuplicate
-JsonInput.FieldNameDuplicateDifferentCasing1
-JsonInput.FieldNameDuplicateDifferentCasing2
JsonInput.FieldNameInSnakeCase.JsonOutput
JsonInput.FieldNameNotQuoted
-JsonInput.FieldNameWithMixedCases.JsonOutput
JsonInput.FloatFieldInfinityNotQuoted
JsonInput.FloatFieldNanNotQuoted
JsonInput.FloatFieldNegativeInfinityNotQuoted
-JsonInput.Int32FieldExponentialFormat.JsonOutput
-JsonInput.Int32FieldExponentialFormat.ProtobufOutput
-JsonInput.Int32FieldFloatTrailingZero.JsonOutput
-JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
JsonInput.Int32FieldLeadingZero
-JsonInput.Int32FieldMaxFloatValue.JsonOutput
-JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
JsonInput.Int32FieldMinFloatValue.JsonOutput
-JsonInput.Int32FieldMinFloatValue.ProtobufOutput
JsonInput.Int32FieldMinValue.JsonOutput
JsonInput.Int32FieldNegativeWithLeadingZero
JsonInput.Int32FieldPlusSign
JsonInput.Int32MapFieldKeyNotQuoted
JsonInput.Int64MapFieldKeyNotQuoted
JsonInput.JsonWithComments
-JsonInput.MapFieldValueIsNull
-JsonInput.OneofFieldDuplicate
JsonInput.OriginalProtoFieldName.JsonOutput
-JsonInput.RepeatedFieldMessageElementIsNull
-JsonInput.RepeatedFieldPrimitiveElementIsNull
-JsonInput.RepeatedFieldTrailingComma
JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
JsonInput.StringFieldNotAString
@@ -66,9 +45,5 @@ JsonInput.StringFieldSurrogateInWrongOrder
JsonInput.StringFieldUnpairedHighSurrogate
JsonInput.StringFieldUnpairedLowSurrogate
JsonInput.StringFieldUppercaseEscapeLetter
-JsonInput.Uint32FieldMaxFloatValue.JsonOutput
-JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
JsonInput.Uint32MapFieldKeyNotQuoted
JsonInput.Uint64MapFieldKeyNotQuoted
-JsonInput.ValueAcceptNull.JsonOutput
-JsonInput.ValueAcceptNull.ProtobufOutput
diff --git a/conformance/failure_list_python-post26.txt b/conformance/failure_list_python-post26.txt
new file mode 100644
index 00000000..19d99b04
--- /dev/null
+++ b/conformance/failure_list_python-post26.txt
@@ -0,0 +1,2 @@
+JsonInput.StringFieldSurrogateInWrongOrder
+JsonInput.StringFieldUnpairedHighSurrogate
diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt
index e69de29b..c9934598 100644
--- a/conformance/failure_list_python.txt
+++ b/conformance/failure_list_python.txt
@@ -0,0 +1,173 @@
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AllFieldAcceptNull.JsonOutput
+JsonInput.Any.JsonOutput
+JsonInput.AnyNested.JsonOutput
+JsonInput.AnyNested.ProtobufOutput
+JsonInput.Any.ProtobufOutput
+JsonInput.AnyUnorderedTypeTag.JsonOutput
+JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+JsonInput.AnyWithDuration.JsonOutput
+JsonInput.AnyWithDuration.ProtobufOutput
+JsonInput.AnyWithFieldMask.JsonOutput
+JsonInput.AnyWithFieldMask.ProtobufOutput
+JsonInput.AnyWithInt32ValueWrapper.JsonOutput
+JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
+JsonInput.AnyWithStruct.JsonOutput
+JsonInput.AnyWithStruct.ProtobufOutput
+JsonInput.AnyWithTimestamp.JsonOutput
+JsonInput.AnyWithTimestamp.ProtobufOutput
+JsonInput.AnyWithValueForInteger.JsonOutput
+JsonInput.AnyWithValueForInteger.ProtobufOutput
+JsonInput.AnyWithValueForJsonObject.JsonOutput
+JsonInput.AnyWithValueForJsonObject.ProtobufOutput
+JsonInput.BoolFieldFalse.JsonOutput
+JsonInput.BoolFieldTrue.JsonOutput
+JsonInput.BoolMapEscapedKey.JsonOutput
+JsonInput.BoolMapField.JsonOutput
+JsonInput.BytesFieldInvalidBase64Characters
+JsonInput.BytesField.JsonOutput
+JsonInput.BytesRepeatedField.JsonOutput
+JsonInput.DoubleFieldInfinity.JsonOutput
+JsonInput.DoubleFieldInfinityNotQuoted
+JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
+JsonInput.DoubleFieldMinNegativeValue.JsonOutput
+JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+JsonInput.DoubleFieldNan.JsonOutput
+JsonInput.DoubleFieldNanNotQuoted
+JsonInput.DoubleFieldNegativeInfinity.JsonOutput
+JsonInput.DoubleFieldNegativeInfinityNotQuoted
+JsonInput.DoubleFieldQuotedValue.JsonOutput
+JsonInput.DoubleFieldTooSmall
+JsonInput.DurationJsonInputTooLarge
+JsonInput.DurationJsonInputTooSmall
+JsonInput.DurationMaxValue.JsonOutput
+JsonInput.DurationMinValue.JsonOutput
+JsonInput.DurationMissingS
+JsonInput.DurationRepeatedValue.JsonOutput
+JsonInput.EnumField.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+JsonInput.EnumFieldNumericValueZero.JsonOutput
+JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.EnumRepeatedField.JsonOutput
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldMask.JsonOutput
+JsonInput.FieldMask.ProtobufOutput
+JsonInput.FieldNameEscaped.JsonOutput
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.JsonOutput
+JsonInput.FieldNameWithNumbers.JsonOutput
+JsonInput.FloatFieldInfinity.JsonOutput
+JsonInput.FloatFieldInfinityNotQuoted
+JsonInput.FloatFieldMaxNegativeValue.JsonOutput
+JsonInput.FloatFieldMaxPositiveValue.JsonOutput
+JsonInput.FloatFieldMinNegativeValue.JsonOutput
+JsonInput.FloatFieldMinPositiveValue.JsonOutput
+JsonInput.FloatFieldNan.JsonOutput
+JsonInput.FloatFieldNanNotQuoted
+JsonInput.FloatFieldNegativeInfinity.JsonOutput
+JsonInput.FloatFieldNegativeInfinityNotQuoted
+JsonInput.FloatFieldQuotedValue.JsonOutput
+JsonInput.FloatFieldTooLarge
+JsonInput.FloatFieldTooSmall
+JsonInput.HelloWorld.JsonOutput
+JsonInput.Int32FieldExponentialFormat.JsonOutput
+JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+JsonInput.Int32FieldMaxFloatValue.JsonOutput
+JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Int32FieldMaxValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+JsonInput.Int32FieldMinValue.JsonOutput
+JsonInput.Int32FieldStringValueEscaped.JsonOutput
+JsonInput.Int32FieldStringValue.JsonOutput
+JsonInput.Int32MapEscapedKey.JsonOutput
+JsonInput.Int32MapField.JsonOutput
+JsonInput.Int64FieldMaxValue.JsonOutput
+JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Int64FieldMinValue.JsonOutput
+JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
+JsonInput.Int64MapEscapedKey.JsonOutput
+JsonInput.Int64MapField.JsonOutput
+JsonInput.MessageField.JsonOutput
+JsonInput.MessageMapField.JsonOutput
+JsonInput.MessageRepeatedField.JsonOutput
+JsonInput.OptionalBoolWrapper.JsonOutput
+JsonInput.OptionalBytesWrapper.JsonOutput
+JsonInput.OptionalDoubleWrapper.JsonOutput
+JsonInput.OptionalFloatWrapper.JsonOutput
+JsonInput.OptionalInt32Wrapper.JsonOutput
+JsonInput.OptionalInt64Wrapper.JsonOutput
+JsonInput.OptionalStringWrapper.JsonOutput
+JsonInput.OptionalUint32Wrapper.JsonOutput
+JsonInput.OptionalUint64Wrapper.JsonOutput
+JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.OriginalProtoFieldName.ProtobufOutput
+JsonInput.PrimitiveRepeatedField.JsonOutput
+JsonInput.RepeatedBoolWrapper.JsonOutput
+JsonInput.RepeatedBytesWrapper.JsonOutput
+JsonInput.RepeatedDoubleWrapper.JsonOutput
+JsonInput.RepeatedFieldMessageElementIsNull
+JsonInput.RepeatedFieldPrimitiveElementIsNull
+JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
+JsonInput.RepeatedFloatWrapper.JsonOutput
+JsonInput.RepeatedInt32Wrapper.JsonOutput
+JsonInput.RepeatedInt64Wrapper.JsonOutput
+JsonInput.RepeatedStringWrapper.JsonOutput
+JsonInput.RepeatedUint32Wrapper.JsonOutput
+JsonInput.RepeatedUint64Wrapper.JsonOutput
+JsonInput.StringFieldEscape.JsonOutput
+JsonInput.StringField.JsonOutput
+JsonInput.StringFieldSurrogatePair.JsonOutput
+JsonInput.StringFieldUnicodeEscape.JsonOutput
+JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
+JsonInput.StringFieldUnicode.JsonOutput
+JsonInput.StringFieldUnpairedLowSurrogate
+JsonInput.StringRepeatedField.JsonOutput
+JsonInput.Struct.JsonOutput
+JsonInput.Struct.ProtobufOutput
+JsonInput.TimestampJsonInputLowercaseT
+JsonInput.TimestampMaxValue.JsonOutput
+JsonInput.TimestampMinValue.JsonOutput
+JsonInput.TimestampRepeatedValue.JsonOutput
+JsonInput.TimestampWithNegativeOffset.JsonOutput
+JsonInput.TimestampWithPositiveOffset.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Uint32FieldMaxValue.JsonOutput
+JsonInput.Uint32MapField.JsonOutput
+JsonInput.Uint64FieldMaxValue.JsonOutput
+JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Uint64MapField.JsonOutput
+JsonInput.ValueAcceptBool.JsonOutput
+JsonInput.ValueAcceptBool.ProtobufOutput
+JsonInput.ValueAcceptFloat.JsonOutput
+JsonInput.ValueAcceptFloat.ProtobufOutput
+JsonInput.ValueAcceptInteger.JsonOutput
+JsonInput.ValueAcceptInteger.ProtobufOutput
+JsonInput.ValueAcceptList.JsonOutput
+JsonInput.ValueAcceptList.ProtobufOutput
+JsonInput.ValueAcceptNull.JsonOutput
+JsonInput.ValueAcceptNull.ProtobufOutput
+JsonInput.ValueAcceptObject.JsonOutput
+JsonInput.ValueAcceptObject.ProtobufOutput
+JsonInput.ValueAcceptString.JsonOutput
+JsonInput.ValueAcceptString.ProtobufOutput
+JsonInput.WrapperTypesWithNullValue.JsonOutput
+ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt
index 4b16a88b..9c710e99 100644
--- a/conformance/failure_list_python_cpp.txt
+++ b/conformance/failure_list_python_cpp.txt
@@ -7,6 +7,177 @@
# TODO(haberman): insert links to corresponding bugs tracking the issue.
# Should we use GitHub issues or the Google-internal bug tracker?
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AllFieldAcceptNull.JsonOutput
+JsonInput.Any.JsonOutput
+JsonInput.AnyNested.JsonOutput
+JsonInput.AnyNested.ProtobufOutput
+JsonInput.Any.ProtobufOutput
+JsonInput.AnyUnorderedTypeTag.JsonOutput
+JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+JsonInput.AnyWithDuration.JsonOutput
+JsonInput.AnyWithDuration.ProtobufOutput
+JsonInput.AnyWithFieldMask.JsonOutput
+JsonInput.AnyWithFieldMask.ProtobufOutput
+JsonInput.AnyWithInt32ValueWrapper.JsonOutput
+JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
+JsonInput.AnyWithStruct.JsonOutput
+JsonInput.AnyWithStruct.ProtobufOutput
+JsonInput.AnyWithTimestamp.JsonOutput
+JsonInput.AnyWithTimestamp.ProtobufOutput
+JsonInput.AnyWithValueForInteger.JsonOutput
+JsonInput.AnyWithValueForInteger.ProtobufOutput
+JsonInput.AnyWithValueForJsonObject.JsonOutput
+JsonInput.AnyWithValueForJsonObject.ProtobufOutput
+JsonInput.BoolFieldFalse.JsonOutput
+JsonInput.BoolFieldTrue.JsonOutput
+JsonInput.BoolMapEscapedKey.JsonOutput
+JsonInput.BoolMapField.JsonOutput
+JsonInput.BytesFieldInvalidBase64Characters
+JsonInput.BytesField.JsonOutput
+JsonInput.BytesRepeatedField.JsonOutput
+JsonInput.DoubleFieldInfinity.JsonOutput
+JsonInput.DoubleFieldInfinityNotQuoted
+JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
+JsonInput.DoubleFieldMinNegativeValue.JsonOutput
+JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+JsonInput.DoubleFieldNan.JsonOutput
+JsonInput.DoubleFieldNanNotQuoted
+JsonInput.DoubleFieldNegativeInfinity.JsonOutput
+JsonInput.DoubleFieldNegativeInfinityNotQuoted
+JsonInput.DoubleFieldQuotedValue.JsonOutput
+JsonInput.DoubleFieldTooSmall
+JsonInput.DurationJsonInputTooLarge
+JsonInput.DurationJsonInputTooSmall
+JsonInput.DurationMaxValue.JsonOutput
+JsonInput.DurationMinValue.JsonOutput
+JsonInput.DurationMissingS
+JsonInput.DurationRepeatedValue.JsonOutput
+JsonInput.EnumField.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+JsonInput.EnumFieldNumericValueZero.JsonOutput
+JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.EnumRepeatedField.JsonOutput
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldMask.JsonOutput
+JsonInput.FieldMask.ProtobufOutput
+JsonInput.FieldNameEscaped.JsonOutput
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.JsonOutput
+JsonInput.FieldNameWithNumbers.JsonOutput
+JsonInput.FloatFieldInfinity.JsonOutput
+JsonInput.FloatFieldInfinityNotQuoted
+JsonInput.FloatFieldMaxNegativeValue.JsonOutput
+JsonInput.FloatFieldMaxPositiveValue.JsonOutput
+JsonInput.FloatFieldMinNegativeValue.JsonOutput
+JsonInput.FloatFieldMinPositiveValue.JsonOutput
+JsonInput.FloatFieldNan.JsonOutput
+JsonInput.FloatFieldNanNotQuoted
+JsonInput.FloatFieldNegativeInfinity.JsonOutput
+JsonInput.FloatFieldNegativeInfinityNotQuoted
+JsonInput.FloatFieldQuotedValue.JsonOutput
+JsonInput.FloatFieldTooLarge
+JsonInput.FloatFieldTooSmall
+JsonInput.HelloWorld.JsonOutput
+JsonInput.Int32FieldExponentialFormat.JsonOutput
+JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+JsonInput.Int32FieldMaxFloatValue.JsonOutput
+JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Int32FieldMaxValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+JsonInput.Int32FieldMinValue.JsonOutput
+JsonInput.Int32FieldStringValueEscaped.JsonOutput
+JsonInput.Int32FieldStringValue.JsonOutput
+JsonInput.Int32MapEscapedKey.JsonOutput
+JsonInput.Int32MapField.JsonOutput
+JsonInput.Int64FieldMaxValue.JsonOutput
+JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Int64FieldMinValue.JsonOutput
+JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
+JsonInput.Int64MapEscapedKey.JsonOutput
+JsonInput.Int64MapField.JsonOutput
+JsonInput.MessageField.JsonOutput
+JsonInput.MessageMapField.JsonOutput
+JsonInput.MessageRepeatedField.JsonOutput
+JsonInput.OptionalBoolWrapper.JsonOutput
+JsonInput.OptionalBytesWrapper.JsonOutput
+JsonInput.OptionalDoubleWrapper.JsonOutput
+JsonInput.OptionalFloatWrapper.JsonOutput
+JsonInput.OptionalInt32Wrapper.JsonOutput
+JsonInput.OptionalInt64Wrapper.JsonOutput
+JsonInput.OptionalStringWrapper.JsonOutput
+JsonInput.OptionalUint32Wrapper.JsonOutput
+JsonInput.OptionalUint64Wrapper.JsonOutput
+JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.OriginalProtoFieldName.ProtobufOutput
+JsonInput.PrimitiveRepeatedField.JsonOutput
+JsonInput.RepeatedBoolWrapper.JsonOutput
+JsonInput.RepeatedBytesWrapper.JsonOutput
+JsonInput.RepeatedDoubleWrapper.JsonOutput
+JsonInput.RepeatedFieldMessageElementIsNull
+JsonInput.RepeatedFieldPrimitiveElementIsNull
+JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
+JsonInput.RepeatedFloatWrapper.JsonOutput
+JsonInput.RepeatedInt32Wrapper.JsonOutput
+JsonInput.RepeatedInt64Wrapper.JsonOutput
+JsonInput.RepeatedStringWrapper.JsonOutput
+JsonInput.RepeatedUint32Wrapper.JsonOutput
+JsonInput.RepeatedUint64Wrapper.JsonOutput
+JsonInput.StringFieldEscape.JsonOutput
+JsonInput.StringField.JsonOutput
+JsonInput.StringFieldSurrogatePair.JsonOutput
+JsonInput.StringFieldUnicodeEscape.JsonOutput
+JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
+JsonInput.StringFieldUnicode.JsonOutput
+JsonInput.StringFieldUnpairedLowSurrogate
+JsonInput.StringRepeatedField.JsonOutput
+JsonInput.Struct.JsonOutput
+JsonInput.Struct.ProtobufOutput
+JsonInput.TimestampJsonInputLowercaseT
+JsonInput.TimestampMaxValue.JsonOutput
+JsonInput.TimestampMinValue.JsonOutput
+JsonInput.TimestampRepeatedValue.JsonOutput
+JsonInput.TimestampWithNegativeOffset.JsonOutput
+JsonInput.TimestampWithPositiveOffset.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Uint32FieldMaxValue.JsonOutput
+JsonInput.Uint32MapField.JsonOutput
+JsonInput.Uint64FieldMaxValue.JsonOutput
+JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Uint64MapField.JsonOutput
+JsonInput.ValueAcceptBool.JsonOutput
+JsonInput.ValueAcceptBool.ProtobufOutput
+JsonInput.ValueAcceptFloat.JsonOutput
+JsonInput.ValueAcceptFloat.ProtobufOutput
+JsonInput.ValueAcceptInteger.JsonOutput
+JsonInput.ValueAcceptInteger.ProtobufOutput
+JsonInput.ValueAcceptList.JsonOutput
+JsonInput.ValueAcceptList.ProtobufOutput
+JsonInput.ValueAcceptNull.JsonOutput
+JsonInput.ValueAcceptNull.ProtobufOutput
+JsonInput.ValueAcceptObject.JsonOutput
+JsonInput.ValueAcceptObject.ProtobufOutput
+JsonInput.ValueAcceptString.JsonOutput
+JsonInput.ValueAcceptString.ProtobufOutput
+JsonInput.WrapperTypesWithNullValue.JsonOutput
+ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInPackedField.BOOL
@@ -23,3 +194,5 @@ ProtobufInput.PrematureEofInPackedField.SINT32
ProtobufInput.PrematureEofInPackedField.SINT64
ProtobufInput.PrematureEofInPackedField.UINT32
ProtobufInput.PrematureEofInPackedField.UINT64
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt
index ff220cb9..1b2e7d94 100644
--- a/conformance/failure_list_ruby.txt
+++ b/conformance/failure_list_ruby.txt
@@ -1,2 +1,337 @@
+# Many of the JSON tests are failing due to a simple bug:
+# fields are not camel-cased at all right now. Once this
+# is fixed, this list should grow a lot shorter.
+
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AllFieldAcceptNull.JsonOutput
+JsonInput.AllFieldAcceptNull.ProtobufOutput
+JsonInput.Any.JsonOutput
+JsonInput.AnyNested.JsonOutput
+JsonInput.AnyNested.ProtobufOutput
+JsonInput.Any.ProtobufOutput
+JsonInput.AnyUnorderedTypeTag.JsonOutput
+JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+JsonInput.AnyWithDuration.JsonOutput
+JsonInput.AnyWithDuration.ProtobufOutput
+JsonInput.AnyWithFieldMask.JsonOutput
+JsonInput.AnyWithFieldMask.ProtobufOutput
+JsonInput.AnyWithInt32ValueWrapper.JsonOutput
+JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
+JsonInput.AnyWithStruct.JsonOutput
+JsonInput.AnyWithStruct.ProtobufOutput
+JsonInput.AnyWithTimestamp.JsonOutput
+JsonInput.AnyWithTimestamp.ProtobufOutput
+JsonInput.AnyWithValueForInteger.JsonOutput
+JsonInput.AnyWithValueForInteger.ProtobufOutput
+JsonInput.AnyWithValueForJsonObject.JsonOutput
+JsonInput.AnyWithValueForJsonObject.ProtobufOutput
+JsonInput.BoolFieldAllCapitalFalse
+JsonInput.BoolFieldAllCapitalTrue
+JsonInput.BoolFieldCamelCaseFalse
+JsonInput.BoolFieldCamelCaseTrue
+JsonInput.BoolFieldDoubleQuotedFalse
+JsonInput.BoolFieldDoubleQuotedTrue
+JsonInput.BoolFieldFalse.JsonOutput
+JsonInput.BoolFieldFalse.ProtobufOutput
+JsonInput.BoolFieldIntegerOne
+JsonInput.BoolFieldIntegerZero
+JsonInput.BoolFieldTrue.JsonOutput
+JsonInput.BoolFieldTrue.ProtobufOutput
+JsonInput.BoolMapEscapedKey.JsonOutput
+JsonInput.BoolMapEscapedKey.ProtobufOutput
+JsonInput.BoolMapField.JsonOutput
+JsonInput.BoolMapFieldKeyNotQuoted
+JsonInput.BoolMapField.ProtobufOutput
+JsonInput.BytesFieldInvalidBase64Characters
+JsonInput.BytesField.JsonOutput
+JsonInput.BytesFieldNoPadding
+JsonInput.BytesField.ProtobufOutput
+JsonInput.BytesRepeatedField.JsonOutput
+JsonInput.BytesRepeatedField.ProtobufOutput
+JsonInput.DoubleFieldInfinity.JsonOutput
+JsonInput.DoubleFieldInfinityNotQuoted
+JsonInput.DoubleFieldInfinity.ProtobufOutput
+JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
+JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
+JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
+JsonInput.DoubleFieldMinNegativeValue.JsonOutput
+JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
+JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
+JsonInput.DoubleFieldNan.JsonOutput
+JsonInput.DoubleFieldNanNotQuoted
+JsonInput.DoubleFieldNan.ProtobufOutput
+JsonInput.DoubleFieldNegativeInfinity.JsonOutput
+JsonInput.DoubleFieldNegativeInfinityNotQuoted
+JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
+JsonInput.DoubleFieldQuotedValue.JsonOutput
+JsonInput.DoubleFieldQuotedValue.ProtobufOutput
+JsonInput.DoubleFieldTooLarge
+JsonInput.DoubleFieldTooSmall
+JsonInput.DurationHas3FractionalDigits.Validator
+JsonInput.DurationHas6FractionalDigits.Validator
+JsonInput.DurationHas9FractionalDigits.Validator
+JsonInput.DurationHasZeroFractionalDigit.Validator
+JsonInput.DurationJsonInputTooLarge
+JsonInput.DurationJsonInputTooSmall
+JsonInput.DurationMaxValue.JsonOutput
+JsonInput.DurationMaxValue.ProtobufOutput
+JsonInput.DurationMinValue.JsonOutput
+JsonInput.DurationMinValue.ProtobufOutput
+JsonInput.DurationMissingS
+JsonInput.DurationRepeatedValue.JsonOutput
+JsonInput.DurationRepeatedValue.ProtobufOutput
+JsonInput.EnumField.JsonOutput
+JsonInput.EnumFieldNotQuoted
+JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+JsonInput.EnumFieldNumericValueZero.JsonOutput
+JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+JsonInput.EnumField.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.EnumRepeatedField.JsonOutput
+JsonInput.EnumRepeatedField.ProtobufOutput
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldMask.JsonOutput
+JsonInput.FieldMask.ProtobufOutput
+JsonInput.FieldNameDuplicate
+JsonInput.FieldNameDuplicateDifferentCasing1
+JsonInput.FieldNameDuplicateDifferentCasing2
+JsonInput.FieldNameEscaped.JsonOutput
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FieldNameNotQuoted
+JsonInput.FieldNameWithMixedCases.JsonOutput
+JsonInput.FieldNameWithMixedCases.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.Validator
+JsonInput.FieldNameWithNumbers.JsonOutput
+JsonInput.FieldNameWithNumbers.ProtobufOutput
+JsonInput.FieldNameWithNumbers.Validator
+JsonInput.FloatFieldInfinity.JsonOutput
+JsonInput.FloatFieldInfinityNotQuoted
+JsonInput.FloatFieldInfinity.ProtobufOutput
+JsonInput.FloatFieldMaxNegativeValue.JsonOutput
+JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput
+JsonInput.FloatFieldMaxPositiveValue.JsonOutput
+JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput
+JsonInput.FloatFieldMinNegativeValue.JsonOutput
+JsonInput.FloatFieldMinNegativeValue.ProtobufOutput
+JsonInput.FloatFieldMinPositiveValue.JsonOutput
+JsonInput.FloatFieldMinPositiveValue.ProtobufOutput
+JsonInput.FloatFieldNan.JsonOutput
+JsonInput.FloatFieldNanNotQuoted
+JsonInput.FloatFieldNan.ProtobufOutput
+JsonInput.FloatFieldNegativeInfinity.JsonOutput
+JsonInput.FloatFieldNegativeInfinityNotQuoted
+JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
+JsonInput.FloatFieldQuotedValue.JsonOutput
+JsonInput.FloatFieldQuotedValue.ProtobufOutput
+JsonInput.FloatFieldTooLarge
+JsonInput.FloatFieldTooSmall
JsonInput.HelloWorld.JsonOutput
JsonInput.HelloWorld.ProtobufOutput
+JsonInput.Int32FieldExponentialFormat.JsonOutput
+JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+JsonInput.Int32FieldLeadingSpace
+JsonInput.Int32FieldLeadingZero
+JsonInput.Int32FieldMaxFloatValue.JsonOutput
+JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Int32FieldMaxValue.JsonOutput
+JsonInput.Int32FieldMaxValue.ProtobufOutput
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+JsonInput.Int32FieldMinValue.JsonOutput
+JsonInput.Int32FieldMinValue.ProtobufOutput
+JsonInput.Int32FieldNegativeWithLeadingZero
+JsonInput.Int32FieldNotInteger
+JsonInput.Int32FieldNotNumber
+JsonInput.Int32FieldPlusSign
+JsonInput.Int32FieldStringValueEscaped.JsonOutput
+JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
+JsonInput.Int32FieldStringValue.JsonOutput
+JsonInput.Int32FieldStringValue.ProtobufOutput
+JsonInput.Int32FieldTooLarge
+JsonInput.Int32FieldTooSmall
+JsonInput.Int32FieldTrailingSpace
+JsonInput.Int32MapEscapedKey.JsonOutput
+JsonInput.Int32MapEscapedKey.ProtobufOutput
+JsonInput.Int32MapField.JsonOutput
+JsonInput.Int32MapFieldKeyNotQuoted
+JsonInput.Int32MapField.ProtobufOutput
+JsonInput.Int64FieldBeString.Validator
+JsonInput.Int64FieldMaxValue.JsonOutput
+JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
+JsonInput.Int64FieldMaxValue.ProtobufOutput
+JsonInput.Int64FieldMinValue.JsonOutput
+JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
+JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
+JsonInput.Int64FieldMinValue.ProtobufOutput
+JsonInput.Int64FieldNotInteger
+JsonInput.Int64FieldNotNumber
+JsonInput.Int64FieldTooLarge
+JsonInput.Int64FieldTooSmall
+JsonInput.Int64MapEscapedKey.JsonOutput
+JsonInput.Int64MapEscapedKey.ProtobufOutput
+JsonInput.Int64MapField.JsonOutput
+JsonInput.Int64MapFieldKeyNotQuoted
+JsonInput.Int64MapField.ProtobufOutput
+JsonInput.JsonWithComments
+JsonInput.MapFieldKeyIsNull
+JsonInput.MapFieldValueIsNull
+JsonInput.MessageField.JsonOutput
+JsonInput.MessageField.ProtobufOutput
+JsonInput.MessageMapField.JsonOutput
+JsonInput.MessageMapField.ProtobufOutput
+JsonInput.MessageRepeatedField.JsonOutput
+JsonInput.MessageRepeatedField.ProtobufOutput
+JsonInput.OneofFieldDuplicate
+JsonInput.OptionalBoolWrapper.JsonOutput
+JsonInput.OptionalBoolWrapper.ProtobufOutput
+JsonInput.OptionalBytesWrapper.JsonOutput
+JsonInput.OptionalBytesWrapper.ProtobufOutput
+JsonInput.OptionalDoubleWrapper.JsonOutput
+JsonInput.OptionalDoubleWrapper.ProtobufOutput
+JsonInput.OptionalFloatWrapper.JsonOutput
+JsonInput.OptionalFloatWrapper.ProtobufOutput
+JsonInput.OptionalInt32Wrapper.JsonOutput
+JsonInput.OptionalInt32Wrapper.ProtobufOutput
+JsonInput.OptionalInt64Wrapper.JsonOutput
+JsonInput.OptionalInt64Wrapper.ProtobufOutput
+JsonInput.OptionalStringWrapper.JsonOutput
+JsonInput.OptionalStringWrapper.ProtobufOutput
+JsonInput.OptionalUint32Wrapper.JsonOutput
+JsonInput.OptionalUint32Wrapper.ProtobufOutput
+JsonInput.OptionalUint64Wrapper.JsonOutput
+JsonInput.OptionalUint64Wrapper.ProtobufOutput
+JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
+JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.PrimitiveRepeatedField.JsonOutput
+JsonInput.PrimitiveRepeatedField.ProtobufOutput
+JsonInput.RepeatedBoolWrapper.JsonOutput
+JsonInput.RepeatedBoolWrapper.ProtobufOutput
+JsonInput.RepeatedBytesWrapper.JsonOutput
+JsonInput.RepeatedBytesWrapper.ProtobufOutput
+JsonInput.RepeatedDoubleWrapper.JsonOutput
+JsonInput.RepeatedDoubleWrapper.ProtobufOutput
+JsonInput.RepeatedFieldMessageElementIsNull
+JsonInput.RepeatedFieldPrimitiveElementIsNull
+JsonInput.RepeatedFieldTrailingComma
+JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
+JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage
+JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString
+JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool
+JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
+JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString
+JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
+JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
+JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage
+JsonInput.RepeatedFloatWrapper.JsonOutput
+JsonInput.RepeatedFloatWrapper.ProtobufOutput
+JsonInput.RepeatedInt32Wrapper.JsonOutput
+JsonInput.RepeatedInt32Wrapper.ProtobufOutput
+JsonInput.RepeatedInt64Wrapper.JsonOutput
+JsonInput.RepeatedInt64Wrapper.ProtobufOutput
+JsonInput.RepeatedStringWrapper.JsonOutput
+JsonInput.RepeatedStringWrapper.ProtobufOutput
+JsonInput.RepeatedUint32Wrapper.JsonOutput
+JsonInput.RepeatedUint32Wrapper.ProtobufOutput
+JsonInput.RepeatedUint64Wrapper.JsonOutput
+JsonInput.RepeatedUint64Wrapper.ProtobufOutput
+JsonInput.StringFieldEscape.JsonOutput
+JsonInput.StringFieldEscape.ProtobufOutput
+JsonInput.StringFieldInvalidEscape
+JsonInput.StringField.JsonOutput
+JsonInput.StringFieldNotAString
+JsonInput.StringField.ProtobufOutput
+JsonInput.StringFieldSurrogateInWrongOrder
+JsonInput.StringFieldSurrogatePair.JsonOutput
+JsonInput.StringFieldSurrogatePair.ProtobufOutput
+JsonInput.StringFieldUnicodeEscape.JsonOutput
+JsonInput.StringFieldUnicodeEscape.ProtobufOutput
+JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
+JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
+JsonInput.StringFieldUnicode.JsonOutput
+JsonInput.StringFieldUnicode.ProtobufOutput
+JsonInput.StringFieldUnpairedHighSurrogate
+JsonInput.StringFieldUnpairedLowSurrogate
+JsonInput.StringFieldUnterminatedEscape
+JsonInput.StringFieldUppercaseEscapeLetter
+JsonInput.StringRepeatedField.JsonOutput
+JsonInput.StringRepeatedField.ProtobufOutput
+JsonInput.Struct.JsonOutput
+JsonInput.Struct.ProtobufOutput
+JsonInput.TimestampHas3FractionalDigits.Validator
+JsonInput.TimestampHas6FractionalDigits.Validator
+JsonInput.TimestampHas9FractionalDigits.Validator
+JsonInput.TimestampHasZeroFractionalDigit.Validator
+JsonInput.TimestampJsonInputLowercaseT
+JsonInput.TimestampJsonInputLowercaseZ
+JsonInput.TimestampJsonInputMissingT
+JsonInput.TimestampJsonInputMissingZ
+JsonInput.TimestampJsonInputTooLarge
+JsonInput.TimestampJsonInputTooSmall
+JsonInput.TimestampMaxValue.JsonOutput
+JsonInput.TimestampMaxValue.ProtobufOutput
+JsonInput.TimestampMinValue.JsonOutput
+JsonInput.TimestampMinValue.ProtobufOutput
+JsonInput.TimestampRepeatedValue.JsonOutput
+JsonInput.TimestampRepeatedValue.ProtobufOutput
+JsonInput.TimestampWithNegativeOffset.JsonOutput
+JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+JsonInput.TimestampWithPositiveOffset.JsonOutput
+JsonInput.TimestampWithPositiveOffset.ProtobufOutput
+JsonInput.TimestampZeroNormalized.Validator
+JsonInput.TrailingCommaInAnObject
+JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Uint32FieldMaxValue.JsonOutput
+JsonInput.Uint32FieldMaxValue.ProtobufOutput
+JsonInput.Uint32FieldNotInteger
+JsonInput.Uint32FieldNotNumber
+JsonInput.Uint32FieldTooLarge
+JsonInput.Uint32MapField.JsonOutput
+JsonInput.Uint32MapFieldKeyNotQuoted
+JsonInput.Uint32MapField.ProtobufOutput
+JsonInput.Uint64FieldBeString.Validator
+JsonInput.Uint64FieldMaxValue.JsonOutput
+JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
+JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
+JsonInput.Uint64FieldMaxValue.ProtobufOutput
+JsonInput.Uint64FieldNotInteger
+JsonInput.Uint64FieldNotNumber
+JsonInput.Uint64FieldTooLarge
+JsonInput.Uint64MapField.JsonOutput
+JsonInput.Uint64MapFieldKeyNotQuoted
+JsonInput.Uint64MapField.ProtobufOutput
+JsonInput.ValueAcceptBool.JsonOutput
+JsonInput.ValueAcceptBool.ProtobufOutput
+JsonInput.ValueAcceptFloat.JsonOutput
+JsonInput.ValueAcceptFloat.ProtobufOutput
+JsonInput.ValueAcceptInteger.JsonOutput
+JsonInput.ValueAcceptInteger.ProtobufOutput
+JsonInput.ValueAcceptList.JsonOutput
+JsonInput.ValueAcceptList.ProtobufOutput
+JsonInput.ValueAcceptNull.JsonOutput
+JsonInput.ValueAcceptNull.ProtobufOutput
+JsonInput.ValueAcceptObject.JsonOutput
+JsonInput.ValueAcceptObject.ProtobufOutput
+JsonInput.ValueAcceptString.JsonOutput
+JsonInput.ValueAcceptString.ProtobufOutput
+JsonInput.WrapperTypesWithNullValue.JsonOutput
+JsonInput.WrapperTypesWithNullValue.ProtobufOutput
+ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/csharp/CHANGES.txt b/csharp/CHANGES.txt
index b29debb8..a87cd4d5 100644
--- a/csharp/CHANGES.txt
+++ b/csharp/CHANGES.txt
@@ -128,7 +128,7 @@ Fixes:
- Issue 12: default value for enumerate fields must be filled out
Other:
-- Rewrite of build using MSBbuild instead of NAnt
+- Rewrite of build using MSbuild instead of NAnt
- Moved to NUnit Version 2.2.8.0
- Changed to using secure .snk for releases
diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
index ba82c0e8..9c845907 100644
--- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
@@ -56,7 +56,7 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void NullValues()
+ public void NullValuesProhibited()
{
TestNullValues<int?>(0);
TestNullValues("");
@@ -65,19 +65,12 @@ namespace Google.Protobuf.Collections
private void TestNullValues<T>(T nonNullValue)
{
- var map = new MapField<int, T>(false);
+ 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;
-
- // Doesn't throw...
- map = new MapField<int, T>(true);
- map.Add(0, nullValue);
- map[0] = nullValue;
- map.Add(1, nonNullValue);
- map[1] = nonNullValue;
}
[Test]
@@ -161,27 +154,6 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void EqualityHandlesNullValues()
- {
- var map1 = new MapField<string, ForeignMessage>();
- map1.Add("a", new ForeignMessage { C = 10 });
- map1.Add("b", null);
-
- var map2 = new MapField<string, ForeignMessage>();
- map2.Add("a", new ForeignMessage { C = 10 });
- map2.Add("b", null);
-
- EqualityTester.AssertEquality(map1, map2);
- // Check the null value isn't ignored entirely...
- Assert.IsTrue(map1.Remove("b"));
- EqualityTester.AssertInequality(map1, map2);
- map1.Add("b", new ForeignMessage());
- EqualityTester.AssertInequality(map1, map2);
- map1["b"] = null;
- EqualityTester.AssertEquality(map1, map2);
- }
-
- [Test]
public void Add_Dictionary()
{
var map1 = new MapField<string, string>
@@ -454,30 +426,6 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void AllowNullValues_Property()
- {
- // Non-message reference type values are non-nullable by default, but can be overridden
- Assert.IsFalse(new MapField<int, string>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, string>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, string>(true).AllowsNullValues);
-
- // Non-nullable value type values are never nullable
- Assert.IsFalse(new MapField<int, int>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, int>(false).AllowsNullValues);
- Assert.Throws<ArgumentException>(() => new MapField<int, int>(true));
-
- // Message type values are nullable by default, but can be overridden
- Assert.IsTrue(new MapField<int, TestAllTypes>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, TestAllTypes>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, TestAllTypes>(true).AllowsNullValues);
-
- // Nullable value type values are nullable by default, but can be overridden
- Assert.IsTrue(new MapField<int, int?>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, int?>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, int?>(true).AllowsNullValues);
- }
-
- [Test]
public void KeysReturnsLiveView()
{
var map = new MapField<string, string>();
diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
index 1163f524..cda7f885 100644
--- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
@@ -221,7 +221,7 @@ namespace Google.Protobuf
},
MapInt32ForeignMessage = {
{ 0, new ForeignMessage { C = 10 } },
- { 5, null },
+ { 5, new ForeignMessage() },
},
MapInt32Enum = {
{ 1, MapEnum.MAP_ENUM_BAR },
@@ -269,6 +269,40 @@ namespace Google.Protobuf
}
[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
diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
index 8473b4be..ace70b00 100644
--- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -37,6 +37,8 @@ using UnitTest.Issues.TestProtos;
using Google.Protobuf.WellKnownTypes;
using Google.Protobuf.Reflection;
+using static Google.Protobuf.JsonParserTest; // For WrapInQuotes
+
namespace Google.Protobuf
{
/// <summary>
@@ -194,13 +196,6 @@ namespace Google.Protobuf
}
[Test]
- public void NullValueForMessage()
- {
- var message = new TestMap { MapInt32ForeignMessage = { { 10, null } } };
- AssertJson("{ 'mapInt32ForeignMessage': { '10': null } }", JsonFormatter.Default.Format(message));
- }
-
- [Test]
[TestCase("a\u17b4b", "a\\u17b4b")] // Explicit
[TestCase("a\u0601b", "a\\u0601b")] // Ranged
[TestCase("a\u0605b", "a\u0605b")] // Passthrough (note lack of double backslash...)
@@ -319,23 +314,28 @@ namespace Google.Protobuf
}
[Test]
- public void TimestampStandalone()
+ [TestCase("1970-01-01T00:00:00Z", 0)]
+ [TestCase("1970-01-01T00:00:00.100Z", 100000000)]
+ [TestCase("1970-01-01T00:00:00.120Z", 120000000)]
+ [TestCase("1970-01-01T00:00:00.123Z", 123000000)]
+ [TestCase("1970-01-01T00:00:00.123400Z", 123400000)]
+ [TestCase("1970-01-01T00:00:00.123450Z", 123450000)]
+ [TestCase("1970-01-01T00:00:00.123456Z", 123456000)]
+ [TestCase("1970-01-01T00:00:00.123456700Z", 123456700)]
+ [TestCase("1970-01-01T00:00:00.123456780Z", 123456780)]
+ [TestCase("1970-01-01T00:00:00.123456789Z", 123456789)]
+ public void TimestampStandalone(string expected, int nanos)
{
- Assert.AreEqual("1970-01-01T00:00:00Z", new Timestamp().ToString());
- Assert.AreEqual("1970-01-01T00:00:00.100Z", new Timestamp { Nanos = 100000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.120Z", new Timestamp { Nanos = 120000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123Z", new Timestamp { Nanos = 123000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123400Z", new Timestamp { Nanos = 123400000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123450Z", new Timestamp { Nanos = 123450000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456Z", new Timestamp { Nanos = 123456000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456700Z", new Timestamp { Nanos = 123456700 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456780Z", new Timestamp { Nanos = 123456780 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456789Z", new Timestamp { Nanos = 123456789 }.ToString());
+ Assert.AreEqual(WrapInQuotes(expected), new Timestamp { Nanos = nanos }.ToString());
+ }
- // One before and one after the Unix epoch
- Assert.AreEqual("1673-06-19T12:34:56Z",
+ [Test]
+ public void TimestampStandalone_FromDateTime()
+ {
+ // One before and one after the Unix epoch, more easily represented via DateTime.
+ Assert.AreEqual("\"1673-06-19T12:34:56Z\"",
new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp().ToString());
- Assert.AreEqual("2015-07-31T10:29:34Z",
+ Assert.AreEqual("\"2015-07-31T10:29:34Z\"",
new DateTime(2015, 7, 31, 10, 29, 34, DateTimeKind.Utc).ToTimestamp().ToString());
}
@@ -367,7 +367,7 @@ namespace Google.Protobuf
[TestCase(1, -100000000, "0.900s")]
public void DurationStandalone(long seconds, int nanoseconds, string expected)
{
- Assert.AreEqual(expected, new Duration { Seconds = seconds, Nanos = nanoseconds }.ToString());
+ Assert.AreEqual(WrapInQuotes(expected), new Duration { Seconds = seconds, Nanos = nanoseconds }.ToString());
}
[Test]
@@ -399,11 +399,11 @@ namespace Google.Protobuf
public void FieldMaskStandalone()
{
var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } };
- Assert.AreEqual(",single,withUnderscore,nested.field.name,nested..doubleDot", fieldMask.ToString());
+ Assert.AreEqual("\",single,withUnderscore,nested.field.name,nested..doubleDot\"", fieldMask.ToString());
// Invalid, but we shouldn't create broken JSON...
fieldMask = new FieldMask { Paths = { "x\\y" } };
- Assert.AreEqual(@"x\\y", fieldMask.ToString());
+ Assert.AreEqual(@"""x\\y""", fieldMask.ToString());
}
[Test]
diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
index 874489e4..303baacc 100644
--- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
@@ -39,9 +39,7 @@ using System;
namespace Google.Protobuf
{
/// <summary>
- /// Unit tests for JSON parsing. Some tests are ignored at the moment as the desired behaviour
- /// isn't fully known, either in terms of which exceptions should be thrown or whether they should
- /// count as valid values.
+ /// Unit tests for JSON parsing.
/// </summary>
public class JsonParserTest
{
@@ -149,7 +147,7 @@ namespace Google.Protobuf
{
ByteString data = ByteString.CopyFrom(1, 2, 3);
// Can't do this with attributes...
- var parsed = JsonParser.Default.Parse<BytesValue>("\"" + data.ToBase64() + "\"");
+ var parsed = JsonParser.Default.Parse<BytesValue>(WrapInQuotes(data.ToBase64()));
var expected = new BytesValue { Value = data };
Assert.AreEqual(expected, parsed);
}
@@ -205,6 +203,8 @@ namespace Google.Protobuf
[Test]
[TestCase("+0")]
+ [TestCase(" 1")]
+ [TestCase("1 ")]
[TestCase("00")]
[TestCase("-00")]
[TestCase("--1")]
@@ -318,7 +318,18 @@ namespace Google.Protobuf
[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)
{
@@ -363,6 +374,10 @@ namespace Google.Protobuf
[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 + "}";
@@ -376,7 +391,8 @@ namespace Google.Protobuf
[TestCase("-00", typeof(InvalidJsonException))]
[TestCase("--1", typeof(InvalidJsonException))]
[TestCase("+1", typeof(InvalidJsonException))]
- [TestCase("1.5", typeof(InvalidProtocolBufferException), Ignore = true, Reason = "Desired behaviour unclear")]
+ [TestCase("1.5", typeof(InvalidProtocolBufferException))]
+ // Value is out of range
[TestCase("1e10", typeof(InvalidProtocolBufferException))]
[TestCase("2147483648", typeof(InvalidProtocolBufferException))]
[TestCase("-2147483649", typeof(InvalidProtocolBufferException))]
@@ -411,8 +427,10 @@ namespace Google.Protobuf
[TestCase("0", 0L)]
[TestCase("1", 1L)]
[TestCase("-1", -1L)]
- [TestCase("9223372036854775807", 9223372036854775807, Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("-9223372036854775808", -9223372036854775808, Ignore = true, Reason = "Desired behaviour unclear")]
+ // 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("9223372036854769664", 9223372036854769664)]
+ [TestCase("-9223372036854775808", -9223372036854775808)]
public void NumberToInt64_Valid(string jsonValue, long expectedParsedValue)
{
string json = "{ \"singleInt64\": " + jsonValue + "}";
@@ -422,8 +440,11 @@ namespace Google.Protobuf
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
- [TestCase("-9223372036854775809", Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("9223372036854775808", Ignore = true, Reason = "Desired behaviour unclear")]
+ [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 + "}";
@@ -433,7 +454,9 @@ namespace Google.Protobuf
[Test]
[TestCase("0", 0UL)]
[TestCase("1", 1UL)]
- [TestCase("18446744073709551615", 18446744073709551615, Ignore = true, Reason = "Desired behaviour unclear")]
+ // ulong.MaxValue isn't representable as a double. This value is the largest double within
+ // the range of ulong.
+ [TestCase("18446744073709500416", 18446744073709500416UL)]
public void NumberToUInt64_Valid(string jsonValue, ulong expectedParsedValue)
{
string json = "{ \"singleUint64\": " + jsonValue + "}";
@@ -475,9 +498,9 @@ namespace Google.Protobuf
}
[Test]
- [TestCase("1.7977e308", Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("-1.7977e308", Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("1e309", Ignore = true, Reason = "Desired behaviour unclear")]
+ [TestCase("1.7977e308")]
+ [TestCase("-1.7977e308")]
+ [TestCase("1e309")]
[TestCase("1,0")]
[TestCase("1.0.0")]
[TestCase("+1")]
@@ -565,9 +588,9 @@ namespace Google.Protobuf
public void Timestamp_Valid(string jsonValue, string expectedFormatted)
{
expectedFormatted = expectedFormatted ?? jsonValue;
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
var parsed = Timestamp.Parser.ParseJson(json);
- Assert.AreEqual(expectedFormatted, parsed.ToString());
+ Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
}
[Test]
@@ -592,7 +615,7 @@ namespace Google.Protobuf
[TestCase("2100-02-29T14:46:23.123456789Z", Description = "Feb 29th on a non-leap-year")]
public void Timestamp_Invalid(string jsonValue)
{
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
Assert.Throws<InvalidProtocolBufferException>(() => Timestamp.Parser.ParseJson(json));
}
@@ -666,9 +689,9 @@ namespace Google.Protobuf
public void Duration_Valid(string jsonValue, string expectedFormatted)
{
expectedFormatted = expectedFormatted ?? jsonValue;
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
var parsed = Duration.Parser.ParseJson(json);
- Assert.AreEqual(expectedFormatted, parsed.ToString());
+ Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
}
// The simplest way of testing that the value has parsed correctly is to reformat it,
@@ -697,7 +720,7 @@ namespace Google.Protobuf
[TestCase("-3155760000000s", Description = "Integer part too long (negative)")]
public void Duration_Invalid(string jsonValue)
{
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
Assert.Throws<InvalidProtocolBufferException>(() => Duration.Parser.ParseJson(json));
}
@@ -713,7 +736,7 @@ namespace Google.Protobuf
[TestCase("fooBar.bazQux", "foo_bar.baz_qux")]
public void FieldMask_Valid(string jsonValue, params string[] expectedPaths)
{
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
var parsed = FieldMask.Parser.ParseJson(json);
CollectionAssert.AreEqual(expectedPaths, parsed.Paths);
}
@@ -789,7 +812,16 @@ namespace Google.Protobuf
var parser63 = new JsonParser(new JsonParser.Settings(63));
Assert.Throws<InvalidProtocolBufferException>(() => parser63.Parse<TestRecursiveMessage>(data64));
+ }
+ /// <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 + '"';
}
}
}
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
index c00b0f41..dfada6bd 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
@@ -2080,7 +2080,7 @@ namespace Google.Protobuf.TestProtos {
public const int DoubleFieldFieldNumber = 10;
private static readonly pbc::MapField<int, double?>.Codec _map_doubleField_codec
= new pbc::MapField<int, double?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<double>(18), 82);
- private readonly pbc::MapField<int, double?> doubleField_ = new pbc::MapField<int, double?>(true);
+ private readonly pbc::MapField<int, double?> doubleField_ = new pbc::MapField<int, double?>();
public pbc::MapField<int, double?> DoubleField {
get { return doubleField_; }
}
@@ -2089,7 +2089,7 @@ namespace Google.Protobuf.TestProtos {
public const int FloatFieldFieldNumber = 11;
private static readonly pbc::MapField<int, float?>.Codec _map_floatField_codec
= new pbc::MapField<int, float?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<float>(18), 90);
- private readonly pbc::MapField<int, float?> floatField_ = new pbc::MapField<int, float?>(true);
+ private readonly pbc::MapField<int, float?> floatField_ = new pbc::MapField<int, float?>();
public pbc::MapField<int, float?> FloatField {
get { return floatField_; }
}
@@ -2098,7 +2098,7 @@ namespace Google.Protobuf.TestProtos {
public const int Int64FieldFieldNumber = 12;
private static readonly pbc::MapField<int, long?>.Codec _map_int64Field_codec
= new pbc::MapField<int, long?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<long>(18), 98);
- private readonly pbc::MapField<int, long?> int64Field_ = new pbc::MapField<int, long?>(true);
+ private readonly pbc::MapField<int, long?> int64Field_ = new pbc::MapField<int, long?>();
public pbc::MapField<int, long?> Int64Field {
get { return int64Field_; }
}
@@ -2107,7 +2107,7 @@ namespace Google.Protobuf.TestProtos {
public const int Uint64FieldFieldNumber = 13;
private static readonly pbc::MapField<int, ulong?>.Codec _map_uint64Field_codec
= new pbc::MapField<int, ulong?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<ulong>(18), 106);
- private readonly pbc::MapField<int, ulong?> uint64Field_ = new pbc::MapField<int, ulong?>(true);
+ private readonly pbc::MapField<int, ulong?> uint64Field_ = new pbc::MapField<int, ulong?>();
public pbc::MapField<int, ulong?> Uint64Field {
get { return uint64Field_; }
}
@@ -2116,7 +2116,7 @@ namespace Google.Protobuf.TestProtos {
public const int Int32FieldFieldNumber = 14;
private static readonly pbc::MapField<int, int?>.Codec _map_int32Field_codec
= new pbc::MapField<int, int?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<int>(18), 114);
- private readonly pbc::MapField<int, int?> int32Field_ = new pbc::MapField<int, int?>(true);
+ private readonly pbc::MapField<int, int?> int32Field_ = new pbc::MapField<int, int?>();
public pbc::MapField<int, int?> Int32Field {
get { return int32Field_; }
}
@@ -2125,7 +2125,7 @@ namespace Google.Protobuf.TestProtos {
public const int Uint32FieldFieldNumber = 15;
private static readonly pbc::MapField<int, uint?>.Codec _map_uint32Field_codec
= new pbc::MapField<int, uint?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<uint>(18), 122);
- private readonly pbc::MapField<int, uint?> uint32Field_ = new pbc::MapField<int, uint?>(true);
+ private readonly pbc::MapField<int, uint?> uint32Field_ = new pbc::MapField<int, uint?>();
public pbc::MapField<int, uint?> Uint32Field {
get { return uint32Field_; }
}
@@ -2134,7 +2134,7 @@ namespace Google.Protobuf.TestProtos {
public const int BoolFieldFieldNumber = 16;
private static readonly pbc::MapField<int, bool?>.Codec _map_boolField_codec
= new pbc::MapField<int, bool?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<bool>(18), 130);
- private readonly pbc::MapField<int, bool?> boolField_ = new pbc::MapField<int, bool?>(true);
+ private readonly pbc::MapField<int, bool?> boolField_ = new pbc::MapField<int, bool?>();
public pbc::MapField<int, bool?> BoolField {
get { return boolField_; }
}
@@ -2143,7 +2143,7 @@ namespace Google.Protobuf.TestProtos {
public const int StringFieldFieldNumber = 17;
private static readonly pbc::MapField<int, string>.Codec _map_stringField_codec
= new pbc::MapField<int, string>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper<string>(18), 138);
- private readonly pbc::MapField<int, string> stringField_ = new pbc::MapField<int, string>(true);
+ private readonly pbc::MapField<int, string> stringField_ = new pbc::MapField<int, string>();
public pbc::MapField<int, string> StringField {
get { return stringField_; }
}
@@ -2152,7 +2152,7 @@ namespace Google.Protobuf.TestProtos {
public const int BytesFieldFieldNumber = 18;
private static readonly pbc::MapField<int, pb::ByteString>.Codec _map_bytesField_codec
= new pbc::MapField<int, pb::ByteString>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper<pb::ByteString>(18), 146);
- private readonly pbc::MapField<int, pb::ByteString> bytesField_ = new pbc::MapField<int, pb::ByteString>(true);
+ private readonly pbc::MapField<int, pb::ByteString> bytesField_ = new pbc::MapField<int, pb::ByteString>();
public pbc::MapField<int, pb::ByteString> BytesField {
get { return bytesField_; }
}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
index c87ceb2f..b72ef982 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
@@ -151,6 +151,8 @@ namespace Google.Protobuf.WellKnownTypes
[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 } },
@@ -158,13 +160,12 @@ namespace Google.Protobuf.WellKnownTypes
{ -1, ByteString.CopyFrom(1, 2, 3) },
{ 10, ByteString.CopyFrom(4, 5, 6) },
{ 1000, ByteString.Empty },
- { 10000, null }
},
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, "" }, { 14, null } },
+ StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" } },
Uint32Field = { { 15, uint.MaxValue }, { 16, uint.MinValue }, { 17, 0U } },
Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } },
};
@@ -224,13 +225,11 @@ namespace Google.Protobuf.WellKnownTypes
[Test]
public void Reflection_MapFields()
{
- // Just a single example... note that we can't have a null value here
- var message = new MapWellKnownTypes { Int32Field = { { 1, 2 }, { 3, null } } };
+ // 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]);
- Assert.IsNull(dictionary[3]);
- Assert.IsTrue(dictionary.Contains(3));
}
[Test]
diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs
index c0ed28ae..04754ae3 100644
--- a/csharp/src/Google.Protobuf/Collections/MapField.cs
+++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -53,6 +53,13 @@ namespace Google.Protobuf.Collections
/// For string keys, the equality comparison is provided by <see cref="StringComparer.Ordinal" />.
/// </para>
/// <para>
+ /// Null values are not permitted in the map, either for wrapper types or regular messages.
+ /// If a map is deserialized from a data stream and the value is missing from an entry, a default value
+ /// is created instead. For primitive types, that is the regular default value (0, the empty string and so
+ /// on); for message types, an empty instance of the message is created, as if the map entry contained a 0-length
+ /// encoded value for the field.
+ /// </para>
+ /// <para>
/// This implementation does not generally prohibit the use of key/value types which are not
/// supported by Protocol Buffers (e.g. using a key type of <code>byte</code>) but nor does it guarantee
/// that all operations will work in such cases.
@@ -61,35 +68,11 @@ namespace Google.Protobuf.Collections
public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary
{
// TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
- private readonly bool allowNullValues;
private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map =
new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>();
private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new LinkedList<KeyValuePair<TKey, TValue>>();
/// <summary>
- /// Constructs a new map field, defaulting the value nullability to only allow null values for message types
- /// and non-nullable value types.
- /// </summary>
- public MapField() : this(typeof(IMessage).IsAssignableFrom(typeof(TValue)) || Nullable.GetUnderlyingType(typeof(TValue)) != null)
- {
- }
-
- /// <summary>
- /// Constructs a new map field, overriding the choice of whether null values are permitted in the map.
- /// This is used by wrapper types, where maps with string and bytes wrappers as the value types
- /// support null values.
- /// </summary>
- /// <param name="allowNullValues">Whether null values are permitted in the map or not.</param>
- public MapField(bool allowNullValues)
- {
- if (allowNullValues && typeof(TValue).IsValueType() && Nullable.GetUnderlyingType(typeof(TValue)) == null)
- {
- throw new ArgumentException("allowNullValues", "Non-nullable value types do not support null values");
- }
- this.allowNullValues = allowNullValues;
- }
-
- /// <summary>
/// Creates a deep clone of this object.
/// </summary>
/// <returns>
@@ -97,13 +80,13 @@ namespace Google.Protobuf.Collections
/// </returns>
public MapField<TKey, TValue> Clone()
{
- var clone = new MapField<TKey, TValue>(allowNullValues);
+ var clone = new MapField<TKey, TValue>();
// Keys are never cloneable. Values might be.
if (typeof(IDeepCloneable<TValue>).IsAssignableFrom(typeof(TValue)))
{
foreach (var pair in list)
{
- clone.Add(pair.Key, pair.Value == null ? pair.Value : ((IDeepCloneable<TValue>)pair.Value).Clone());
+ clone.Add(pair.Key, ((IDeepCloneable<TValue>)pair.Value).Clone());
}
}
else
@@ -217,7 +200,7 @@ namespace Google.Protobuf.Collections
{
Preconditions.CheckNotNullUnconstrained(key, "key");
// value == null check here is redundant, but avoids boxing.
- if (value == null && !allowNullValues)
+ if (value == null)
{
Preconditions.CheckNotNullUnconstrained(value, "value");
}
@@ -246,7 +229,7 @@ namespace Google.Protobuf.Collections
public ICollection<TValue> Values { get { return new MapView<TValue>(this, pair => pair.Value, ContainsValue); } }
/// <summary>
- /// Adds the specified entries to the map.
+ /// Adds the specified entries to the map. The keys and values are not automatically cloned.
/// </summary>
/// <param name="entries">The entries to add to the map.</param>
public void Add(IDictionary<TKey, TValue> entries)
@@ -347,11 +330,6 @@ namespace Google.Protobuf.Collections
}
/// <summary>
- /// Returns whether or not this map allows values to be null.
- /// </summary>
- public bool AllowsNullValues { get { return allowNullValues; } }
-
- /// <summary>
/// Gets the number of elements contained in the map.
/// </summary>
public int Count { get { return list.Count; } }
@@ -632,6 +610,8 @@ namespace Google.Protobuf.Collections
/// </summary>
internal class MessageAdapter : IMessage
{
+ private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
+
private readonly Codec codec;
internal TKey Key { get; set; }
internal TValue Value { get; set; }
@@ -665,6 +645,13 @@ namespace Google.Protobuf.Collections
input.SkipLastField();
}
}
+
+ // Corner case: a map entry with a key but no value, where the value type is a message.
+ // Read it as if we'd seen an input stream with no data (i.e. create a "default" message).
+ if (Value == null)
+ {
+ Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
+ }
}
public void WriteTo(CodedOutputStream output)
diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs
index 6ee8e2f9..c2b8d268 100644
--- a/csharp/src/Google.Protobuf/FieldCodec.cs
+++ b/csharp/src/Google.Protobuf/FieldCodec.cs
@@ -354,11 +354,6 @@ namespace Google.Protobuf
// Otherwise it's the default value of the CLR type
}
- private static Func<T, bool> CreateDefaultValueCheck<TTmp>(Func<TTmp, bool> check)
- {
- return (Func<T, bool>)(object)check;
- }
-
private readonly Func<CodedInputStream, T> reader;
private readonly Action<CodedOutputStream, T> writer;
private readonly Func<T, int> sizeCalculator;
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 7b99f314..bde17903 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -142,7 +142,7 @@ namespace Google.Protobuf
StringBuilder builder = new StringBuilder();
if (message.Descriptor.IsWellKnownType)
{
- WriteWellKnownTypeValue(builder, message.Descriptor, message, false);
+ WriteWellKnownTypeValue(builder, message.Descriptor, message);
}
else
{
@@ -393,7 +393,7 @@ namespace Google.Protobuf
IMessage message = (IMessage) value;
if (message.Descriptor.IsWellKnownType)
{
- WriteWellKnownTypeValue(builder, message.Descriptor, value, true);
+ WriteWellKnownTypeValue(builder, message.Descriptor, value);
}
else
{
@@ -412,7 +412,7 @@ namespace Google.Protobuf
/// values are using the embedded well-known types, in order to allow for dynamic messages
/// in the future.
/// </summary>
- private void WriteWellKnownTypeValue(StringBuilder builder, MessageDescriptor descriptor, object value, bool inField)
+ private void WriteWellKnownTypeValue(StringBuilder builder, MessageDescriptor descriptor, object value)
{
// Currently, we can never actually get here, because null values are always handled by the caller. But if we *could*,
// this would do the right thing.
@@ -438,17 +438,17 @@ namespace Google.Protobuf
}
if (descriptor.FullName == Timestamp.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteTimestamp, inField);
+ WriteTimestamp(builder, (IMessage) value);
return;
}
if (descriptor.FullName == Duration.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteDuration, inField);
+ WriteDuration(builder, (IMessage) value);
return;
}
if (descriptor.FullName == FieldMask.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteFieldMask, inField);
+ WriteFieldMask(builder, (IMessage) value);
return;
}
if (descriptor.FullName == Struct.Descriptor.FullName)
@@ -475,26 +475,9 @@ namespace Google.Protobuf
WriteMessage(builder, (IMessage) value);
}
- /// <summary>
- /// Some well-known types end up as string values... so they need wrapping in quotes, but only
- /// when they're being used as fields within another message.
- /// </summary>
- private void MaybeWrapInString(StringBuilder builder, object value, Action<StringBuilder, IMessage> action, bool inField)
- {
- if (inField)
- {
- builder.Append('"');
- action(builder, (IMessage) value);
- builder.Append('"');
- }
- else
- {
- action(builder, (IMessage) value);
- }
- }
-
private void WriteTimestamp(StringBuilder builder, IMessage value)
{
+ builder.Append('"');
// TODO: In the common case where this *is* using the built-in Timestamp type, we could
// avoid all the reflection at this point, by casting to Timestamp. In the interests of
// avoiding subtle bugs, don't do that until we've implemented DynamicMessage so that we can prove
@@ -509,11 +492,12 @@ namespace Google.Protobuf
DateTime dateTime = normalized.ToDateTime();
builder.Append(dateTime.ToString("yyyy'-'MM'-'dd'T'HH:mm:ss", CultureInfo.InvariantCulture));
AppendNanoseconds(builder, Math.Abs(normalized.Nanos));
- builder.Append('Z');
+ builder.Append("Z\"");
}
private void WriteDuration(StringBuilder builder, IMessage value)
{
+ builder.Append('"');
// TODO: Same as for WriteTimestamp
int nanos = (int) value.Descriptor.Fields[Duration.NanosFieldNumber].Accessor.GetValue(value);
long seconds = (long) value.Descriptor.Fields[Duration.SecondsFieldNumber].Accessor.GetValue(value);
@@ -530,13 +514,13 @@ namespace Google.Protobuf
builder.Append(normalized.Seconds.ToString("d", CultureInfo.InvariantCulture));
AppendNanoseconds(builder, Math.Abs(normalized.Nanos));
- builder.Append('s');
+ builder.Append("s\"");
}
private void WriteFieldMask(StringBuilder builder, IMessage value)
{
IList paths = (IList) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
- AppendEscapedString(builder, string.Join(",", paths.Cast<string>().Select(ToCamelCase)));
+ WriteString(builder, string.Join(",", paths.Cast<string>().Select(ToCamelCase)));
}
private void WriteAny(StringBuilder builder, IMessage value)
@@ -566,7 +550,7 @@ namespace Google.Protobuf
builder.Append(PropertySeparator);
WriteString(builder, AnyWellKnownTypeValueField);
builder.Append(NameValueSeparator);
- WriteWellKnownTypeValue(builder, descriptor, message, true);
+ WriteWellKnownTypeValue(builder, descriptor, message);
}
else
{
@@ -674,7 +658,7 @@ namespace Google.Protobuf
case Value.ListValueFieldNumber:
// Structs and ListValues are nested messages, and already well-known types.
var nestedMessage = (IMessage) specifiedField.Accessor.GetValue(message);
- WriteWellKnownTypeValue(builder, nestedMessage.Descriptor, nestedMessage, true);
+ WriteWellKnownTypeValue(builder, nestedMessage.Descriptor, nestedMessage);
return;
case Value.NullValueFieldNumber:
WriteNull(builder);
@@ -771,15 +755,6 @@ namespace Google.Protobuf
private void WriteString(StringBuilder builder, string text)
{
builder.Append('"');
- AppendEscapedString(builder, text);
- builder.Append('"');
- }
-
- /// <summary>
- /// Appends the given text to the string builder, escaping as required.
- /// </summary>
- private void AppendEscapedString(StringBuilder builder, string text)
- {
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
@@ -839,6 +814,7 @@ namespace Google.Protobuf
break;
}
}
+ builder.Append('"');
}
private const string Hex = "0123456789abcdef";
diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs
index 95f9ad35..300a66b4 100644
--- a/csharp/src/Google.Protobuf/JsonParser.cs
+++ b/csharp/src/Google.Protobuf/JsonParser.cs
@@ -540,17 +540,17 @@ namespace Google.Protobuf
case FieldType.Int32:
case FieldType.SInt32:
case FieldType.SFixed32:
- return ParseNumericString(keyText, int.Parse, false);
+ return ParseNumericString(keyText, int.Parse);
case FieldType.UInt32:
case FieldType.Fixed32:
- return ParseNumericString(keyText, uint.Parse, false);
+ return ParseNumericString(keyText, uint.Parse);
case FieldType.Int64:
case FieldType.SInt64:
case FieldType.SFixed64:
- return ParseNumericString(keyText, long.Parse, false);
+ return ParseNumericString(keyText, long.Parse);
case FieldType.UInt64:
case FieldType.Fixed64:
- return ParseNumericString(keyText, ulong.Parse, false);
+ return ParseNumericString(keyText, ulong.Parse);
default:
throw new InvalidProtocolBufferException("Invalid field type for map: " + field.FieldType);
}
@@ -561,7 +561,6 @@ namespace Google.Protobuf
double value = token.NumberValue;
checked
{
- // TODO: Validate that it's actually an integer, possibly in terms of the textual representation?
try
{
switch (field.FieldType)
@@ -569,16 +568,20 @@ namespace Google.Protobuf
case FieldType.Int32:
case FieldType.SInt32:
case FieldType.SFixed32:
+ CheckInteger(value);
return (int) value;
case FieldType.UInt32:
case FieldType.Fixed32:
+ CheckInteger(value);
return (uint) value;
case FieldType.Int64:
case FieldType.SInt64:
case FieldType.SFixed64:
+ CheckInteger(value);
return (long) value;
case FieldType.UInt64:
case FieldType.Fixed64:
+ CheckInteger(value);
return (ulong) value;
case FieldType.Double:
return value;
@@ -597,20 +600,32 @@ namespace Google.Protobuf
{
return float.NegativeInfinity;
}
- throw new InvalidProtocolBufferException("Value out of range: " + value);
+ throw new InvalidProtocolBufferException($"Value out of range: {value}");
}
return (float) value;
default:
- throw new InvalidProtocolBufferException("Unsupported conversion from JSON number for field type " + field.FieldType);
+ throw new InvalidProtocolBufferException($"Unsupported conversion from JSON number for field type {field.FieldType}");
}
}
catch (OverflowException)
{
- throw new InvalidProtocolBufferException("Value out of range: " + value);
+ throw new InvalidProtocolBufferException($"Value out of range: {value}");
}
}
}
+ private static void CheckInteger(double value)
+ {
+ if (double.IsInfinity(value) || double.IsNaN(value))
+ {
+ throw new InvalidProtocolBufferException($"Value not an integer: {value}");
+ }
+ if (value != Math.Floor(value))
+ {
+ throw new InvalidProtocolBufferException($"Value not an integer: {value}");
+ }
+ }
+
private static object ParseSingleStringValue(FieldDescriptor field, string text)
{
switch (field.FieldType)
@@ -622,43 +637,35 @@ namespace Google.Protobuf
case FieldType.Int32:
case FieldType.SInt32:
case FieldType.SFixed32:
- return ParseNumericString(text, int.Parse, false);
+ return ParseNumericString(text, int.Parse);
case FieldType.UInt32:
case FieldType.Fixed32:
- return ParseNumericString(text, uint.Parse, false);
+ return ParseNumericString(text, uint.Parse);
case FieldType.Int64:
case FieldType.SInt64:
case FieldType.SFixed64:
- return ParseNumericString(text, long.Parse, false);
+ return ParseNumericString(text, long.Parse);
case FieldType.UInt64:
case FieldType.Fixed64:
- return ParseNumericString(text, ulong.Parse, false);
+ return ParseNumericString(text, ulong.Parse);
case FieldType.Double:
- double d = ParseNumericString(text, double.Parse, true);
- // double.Parse can return +/- infinity on Mono for non-infinite values which are out of range for double.
- if (double.IsInfinity(d) && !text.Contains("Infinity"))
- {
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
- }
+ double d = ParseNumericString(text, double.Parse);
+ ValidateInfinityAndNan(text, double.IsPositiveInfinity(d), double.IsNegativeInfinity(d), double.IsNaN(d));
return d;
case FieldType.Float:
- float f = ParseNumericString(text, float.Parse, true);
- // float.Parse can return +/- infinity on Mono for non-infinite values which are out of range for float.
- if (float.IsInfinity(f) && !text.Contains("Infinity"))
- {
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
- }
+ float f = ParseNumericString(text, float.Parse);
+ ValidateInfinityAndNan(text, float.IsPositiveInfinity(f), float.IsNegativeInfinity(f), float.IsNaN(f));
return f;
case FieldType.Enum:
var enumValue = field.EnumType.FindValueByName(text);
if (enumValue == null)
{
- throw new InvalidProtocolBufferException("Invalid enum value: " + text + " for enum type: " + field.EnumType.FullName);
+ throw new InvalidProtocolBufferException($"Invalid enum value: {text} for enum type: {field.EnumType.FullName}");
}
// Just return it as an int, and let the CLR convert it.
return enumValue.Number;
default:
- throw new InvalidProtocolBufferException("Unsupported conversion from JSON string for field type " + field.FieldType);
+ throw new InvalidProtocolBufferException($"Unsupported conversion from JSON string for field type {field.FieldType}");
}
}
@@ -670,43 +677,53 @@ namespace Google.Protobuf
return field.MessageType.Parser.CreateTemplate();
}
- private static T ParseNumericString<T>(string text, Func<string, NumberStyles, IFormatProvider, T> parser, bool floatingPoint)
+ private static T ParseNumericString<T>(string text, Func<string, NumberStyles, IFormatProvider, T> parser)
{
- // TODO: Prohibit leading zeroes (but allow 0!)
- // TODO: Validate handling of "Infinity" etc. (Should be case sensitive, no leading whitespace etc)
// Can't prohibit this with NumberStyles.
if (text.StartsWith("+"))
{
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
if (text.StartsWith("0") && text.Length > 1)
{
if (text[1] >= '0' && text[1] <= '9')
{
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
}
else if (text.StartsWith("-0") && text.Length > 2)
{
if (text[2] >= '0' && text[2] <= '9')
{
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
}
try
{
- var styles = floatingPoint
- ? NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent
- : NumberStyles.AllowLeadingSign;
- return parser(text, styles, CultureInfo.InvariantCulture);
+ return parser(text, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
}
catch (FormatException)
{
- throw new InvalidProtocolBufferException("Invalid numeric value for type: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value for type: {text}");
}
catch (OverflowException)
{
- throw new InvalidProtocolBufferException("Value out of range: " + text);
+ throw new InvalidProtocolBufferException($"Value out of range: {text}");
+ }
+ }
+
+ /// <summary>
+ /// Checks that any infinite/NaN values originated from the correct text.
+ /// This corrects the lenient whitespace handling of double.Parse/float.Parse, as well as the
+ /// way that Mono parses out-of-range values as infinity.
+ /// </summary>
+ private static void ValidateInfinityAndNan(string text, bool isPositiveInfinity, bool isNegativeInfinity, bool isNaN)
+ {
+ if ((isPositiveInfinity && text != "Infinity") ||
+ (isNegativeInfinity && text != "-Infinity") ||
+ (isNaN && text != "NaN"))
+ {
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
}
@@ -719,7 +736,7 @@ namespace Google.Protobuf
var match = TimestampRegex.Match(token.StringValue);
if (!match.Success)
{
- throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue);
+ throw new InvalidProtocolBufferException($"Invalid Timestamp value: {token.StringValue}");
}
var dateTime = match.Groups["datetime"].Value;
var subseconds = match.Groups["subseconds"].Value;
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
index efa60a68..ff391fc0 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
@@ -61,8 +61,8 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// If the embedded message type is well-known and has a custom JSON
/// representation, that representation will be embedded adding a field
- /// `value` which holds the custom JSON in addition to the the `@type`
- /// field. Example (for message [google.protobuf.Duration][google.protobuf.Duration]):
+ /// `value` which holds the custom JSON in addition to the `@type`
+ /// field. Example (for message [google.protobuf.Duration][]):
///
/// {
/// "@type": "type.googleapis.com/google.protobuf.Duration",
@@ -110,7 +110,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// * If no schema is provided, `https` is assumed.
/// * The last segment of the URL's path must represent the fully
/// qualified name of the type (as in `path/google.protobuf.Duration`).
- /// * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
+ /// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
/// value in binary format, or produce an error.
/// * Applications are allowed to cache lookup results based on the
/// URL, or have them precompiled into a binary to avoid any
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
index 1b925b9c..ccb82a94 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
@@ -653,7 +653,6 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// package google.storage.v2;
/// service Storage {
- /// // (-- see AccessControl.GetAcl --)
/// rpc GetAcl(GetAclRequest) returns (Acl);
///
/// // Get a data record.
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
index d568a811..5cdd43c4 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
@@ -24,9 +24,9 @@ namespace Google.Protobuf.WellKnownTypes {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1",
- "ZiIHCgVFbXB0eUJNChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
- "UAGgAQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNi",
- "BnByb3RvMw=="));
+ "ZiIHCgVFbXB0eUJQChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
+ "UAGgAQH4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
+ "ZXNiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
index 0cd5952a..2bfb6700 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
@@ -69,7 +69,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// z: 8
///
/// The result will not contain specific values for fields x,y and z
- /// (there value will be set to the default, and omitted in proto text
+ /// (their value will be set to the default, and omitted in proto text
/// output):
///
/// f {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
index adee4bb4..f0d656fa 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
@@ -25,9 +25,9 @@ namespace Google.Protobuf.WellKnownTypes {
string.Concat(
"Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv",
"dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY",
- "AiABKAVCUQoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
- "AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
- "cHJvdG8z"));
+ "AiABKAVCVAoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
+ "AaABAfgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBl",
+ "c2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
index a76d02b4..b5766916 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
@@ -30,38 +30,39 @@ namespace Google.Protobuf.WellKnownTypes {
"b2ZzGAMgAygJEigKB29wdGlvbnMYBCADKAsyFy5nb29nbGUucHJvdG9idWYu",
"T3B0aW9uEjYKDnNvdXJjZV9jb250ZXh0GAUgASgLMh4uZ29vZ2xlLnByb3Rv",
"YnVmLlNvdXJjZUNvbnRleHQSJwoGc3ludGF4GAYgASgOMhcuZ29vZ2xlLnBy",
- "b3RvYnVmLlN5bnRheCK+BQoFRmllbGQSKQoEa2luZBgBIAEoDjIbLmdvb2ds",
+ "b3RvYnVmLlN5bnRheCLVBQoFRmllbGQSKQoEa2luZBgBIAEoDjIbLmdvb2ds",
"ZS5wcm90b2J1Zi5GaWVsZC5LaW5kEjcKC2NhcmRpbmFsaXR5GAIgASgOMiIu",
"Z29vZ2xlLnByb3RvYnVmLkZpZWxkLkNhcmRpbmFsaXR5Eg4KBm51bWJlchgD",
"IAEoBRIMCgRuYW1lGAQgASgJEhAKCHR5cGVfdXJsGAYgASgJEhMKC29uZW9m",
"X2luZGV4GAcgASgFEg4KBnBhY2tlZBgIIAEoCBIoCgdvcHRpb25zGAkgAygL",
- "MhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhIRCglqc29uX25hbWUYCiABKAki",
- "yAIKBEtpbmQSEAoMVFlQRV9VTktOT1dOEAASDwoLVFlQRV9ET1VCTEUQARIO",
- "CgpUWVBFX0ZMT0FUEAISDgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0",
- "EAQSDgoKVFlQRV9JTlQzMhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVf",
- "RklYRUQzMhAHEg0KCVRZUEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoK",
- "VFlQRV9HUk9VUBAKEhAKDFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQ",
- "DBIPCgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJ",
- "WEVEMzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIP",
- "CgtUWVBFX1NJTlQ2NBASInQKC0NhcmRpbmFsaXR5EhcKE0NBUkRJTkFMSVRZ",
- "X1VOS05PV04QABIYChRDQVJESU5BTElUWV9PUFRJT05BTBABEhgKFENBUkRJ",
- "TkFMSVRZX1JFUVVJUkVEEAISGAoUQ0FSRElOQUxJVFlfUkVQRUFURUQQAyLO",
- "AQoERW51bRIMCgRuYW1lGAEgASgJEi0KCWVudW12YWx1ZRgCIAMoCzIaLmdv",
- "b2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUSKAoHb3B0aW9ucxgDIAMoCzIXLmdv",
- "b2dsZS5wcm90b2J1Zi5PcHRpb24SNgoOc291cmNlX2NvbnRleHQYBCABKAsy",
- "Hi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dBInCgZzeW50YXgYBSAB",
- "KA4yFy5nb29nbGUucHJvdG9idWYuU3ludGF4IlMKCUVudW1WYWx1ZRIMCgRu",
- "YW1lGAEgASgJEg4KBm51bWJlchgCIAEoBRIoCgdvcHRpb25zGAMgAygLMhcu",
- "Z29vZ2xlLnByb3RvYnVmLk9wdGlvbiI7CgZPcHRpb24SDAoEbmFtZRgBIAEo",
- "CRIjCgV2YWx1ZRgCIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkqLgoGU3lu",
- "dGF4EhEKDVNZTlRBWF9QUk9UTzIQABIRCg1TWU5UQVhfUFJPVE8zEAFCTAoT",
- "Y29tLmdvb2dsZS5wcm90b2J1ZkIJVHlwZVByb3RvUAGgAQGiAgNHUEKqAh5H",
- "b29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
+ "MhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhIRCglqc29uX25hbWUYCiABKAkS",
+ "FQoNZGVmYXVsdF92YWx1ZRgLIAEoCSLIAgoES2luZBIQCgxUWVBFX1VOS05P",
+ "V04QABIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBF",
+ "X0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoM",
+ "VFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09M",
+ "EAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9N",
+ "RVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJ",
+ "VFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVE",
+ "NjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIidAoLQ2Fy",
+ "ZGluYWxpdHkSFwoTQ0FSRElOQUxJVFlfVU5LTk9XThAAEhgKFENBUkRJTkFM",
+ "SVRZX09QVElPTkFMEAESGAoUQ0FSRElOQUxJVFlfUkVRVUlSRUQQAhIYChRD",
+ "QVJESU5BTElUWV9SRVBFQVRFRBADIs4BCgRFbnVtEgwKBG5hbWUYASABKAkS",
+ "LQoJZW51bXZhbHVlGAIgAygLMhouZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1",
+ "ZRIoCgdvcHRpb25zGAMgAygLMhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhI2",
+ "Cg5zb3VyY2VfY29udGV4dBgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5Tb3Vy",
+ "Y2VDb250ZXh0EicKBnN5bnRheBgFIAEoDjIXLmdvb2dsZS5wcm90b2J1Zi5T",
+ "eW50YXgiUwoJRW51bVZhbHVlEgwKBG5hbWUYASABKAkSDgoGbnVtYmVyGAIg",
+ "ASgFEigKB29wdGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9u",
+ "IjsKBk9wdGlvbhIMCgRuYW1lGAEgASgJEiMKBXZhbHVlGAIgASgLMhQuZ29v",
+ "Z2xlLnByb3RvYnVmLkFueSouCgZTeW50YXgSEQoNU1lOVEFYX1BST1RPMhAA",
+ "EhEKDVNZTlRBWF9QUk9UTzMQAUJMChNjb20uZ29vZ2xlLnByb3RvYnVmQglU",
+ "eXBlUHJvdG9QAaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25v",
+ "d25UeXBlc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, },
new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, new pbr::GeneratedCodeInfo[] {
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), global::Google.Protobuf.WellKnownTypes.Type.Parser, new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), global::Google.Protobuf.WellKnownTypes.Field.Parser, new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null),
+ new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), global::Google.Protobuf.WellKnownTypes.Field.Parser, new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName", "DefaultValue" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null),
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Enum), global::Google.Protobuf.WellKnownTypes.Enum.Parser, new[]{ "Name", "Enumvalue", "Options", "SourceContext", "Syntax" }, null, null, null),
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.EnumValue), global::Google.Protobuf.WellKnownTypes.EnumValue.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Option), global::Google.Protobuf.WellKnownTypes.Option.Parser, new[]{ "Name", "Value" }, null, null, null)
@@ -72,15 +73,15 @@ namespace Google.Protobuf.WellKnownTypes {
}
#region Enums
/// <summary>
- /// Syntax specifies the syntax in which a service element was defined.
+ /// The syntax in which a protocol buffer element is defined.
/// </summary>
public enum Syntax {
/// <summary>
- /// Syntax "proto2"
+ /// Syntax `proto2`.
/// </summary>
SYNTAX_PROTO2 = 0,
/// <summary>
- /// Syntax "proto3"
+ /// Syntax `proto3`.
/// </summary>
SYNTAX_PROTO3 = 1,
}
@@ -89,7 +90,7 @@ namespace Google.Protobuf.WellKnownTypes {
#region Messages
/// <summary>
- /// A light-weight descriptor for a proto message type.
+ /// A protocol buffer message type.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Type : pb::IMessage<Type> {
@@ -154,7 +155,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForString(26);
private readonly pbc::RepeatedField<string> oneofs_ = new pbc::RepeatedField<string>();
/// <summary>
- /// The list of oneof definitions.
+ /// The list of types appearing in `oneof` definitions in this type.
/// </summary>
public pbc::RepeatedField<string> Oneofs {
get { return oneofs_; }
@@ -166,7 +167,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(34, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// The proto options.
+ /// The protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -330,7 +331,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
/// <summary>
- /// Field represents a single field of a message type.
+ /// A single field of a message type.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Field : pb::IMessage<Field> {
@@ -361,6 +362,7 @@ namespace Google.Protobuf.WellKnownTypes {
packed_ = other.packed_;
options_ = other.options_.Clone();
jsonName_ = other.jsonName_;
+ defaultValue_ = other.defaultValue_;
}
public Field Clone() {
@@ -371,7 +373,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int KindFieldNumber = 1;
private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN;
/// <summary>
- /// The field kind.
+ /// The field type.
/// </summary>
public global::Google.Protobuf.WellKnownTypes.Field.Types.Kind Kind {
get { return kind_; }
@@ -384,7 +386,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int CardinalityFieldNumber = 2;
private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN;
/// <summary>
- /// The field cardinality, i.e. optional/required/repeated.
+ /// The field cardinality.
/// </summary>
public global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality Cardinality {
get { return cardinality_; }
@@ -397,7 +399,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int NumberFieldNumber = 3;
private int number_;
/// <summary>
- /// The proto field number.
+ /// The field number.
/// </summary>
public int Number {
get { return number_; }
@@ -423,8 +425,8 @@ namespace Google.Protobuf.WellKnownTypes {
public const int TypeUrlFieldNumber = 6;
private string typeUrl_ = "";
/// <summary>
- /// The type URL (without the scheme) when the type is MESSAGE or ENUM,
- /// such as `type.googleapis.com/google.protobuf.Empty`.
+ /// The field type URL, without the scheme, for message or enumeration
+ /// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
/// </summary>
public string TypeUrl {
get { return typeUrl_; }
@@ -437,7 +439,8 @@ namespace Google.Protobuf.WellKnownTypes {
public const int OneofIndexFieldNumber = 7;
private int oneofIndex_;
/// <summary>
- /// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
+ /// The index of the field type in `Type.oneofs`, for message or enumeration
+ /// types. The first type has index 1; zero means the type is not in the list.
/// </summary>
public int OneofIndex {
get { return oneofIndex_; }
@@ -465,7 +468,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(74, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// The proto options.
+ /// The protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -475,7 +478,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int JsonNameFieldNumber = 10;
private string jsonName_ = "";
/// <summary>
- /// The JSON name for this field.
+ /// The field JSON name.
/// </summary>
public string JsonName {
get { return jsonName_; }
@@ -484,6 +487,19 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ /// <summary>Field number for the "default_value" field.</summary>
+ public const int DefaultValueFieldNumber = 11;
+ private string defaultValue_ = "";
+ /// <summary>
+ /// The string value of the default value of this field. Proto2 syntax only.
+ /// </summary>
+ public string DefaultValue {
+ get { return defaultValue_; }
+ set {
+ defaultValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ }
+ }
+
public override bool Equals(object other) {
return Equals(other as Field);
}
@@ -504,6 +520,7 @@ namespace Google.Protobuf.WellKnownTypes {
if (Packed != other.Packed) return false;
if(!options_.Equals(other.options_)) return false;
if (JsonName != other.JsonName) return false;
+ if (DefaultValue != other.DefaultValue) return false;
return true;
}
@@ -518,6 +535,7 @@ namespace Google.Protobuf.WellKnownTypes {
if (Packed != false) hash ^= Packed.GetHashCode();
hash ^= options_.GetHashCode();
if (JsonName.Length != 0) hash ^= JsonName.GetHashCode();
+ if (DefaultValue.Length != 0) hash ^= DefaultValue.GetHashCode();
return hash;
}
@@ -559,6 +577,10 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteRawTag(82);
output.WriteString(JsonName);
}
+ if (DefaultValue.Length != 0) {
+ output.WriteRawTag(90);
+ output.WriteString(DefaultValue);
+ }
}
public int CalculateSize() {
@@ -588,6 +610,9 @@ namespace Google.Protobuf.WellKnownTypes {
if (JsonName.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonName);
}
+ if (DefaultValue.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(DefaultValue);
+ }
return size;
}
@@ -620,6 +645,9 @@ namespace Google.Protobuf.WellKnownTypes {
if (other.JsonName.Length != 0) {
JsonName = other.JsonName;
}
+ if (other.DefaultValue.Length != 0) {
+ DefaultValue = other.DefaultValue;
+ }
}
public void MergeFrom(pb::CodedInputStream input) {
@@ -665,6 +693,10 @@ namespace Google.Protobuf.WellKnownTypes {
JsonName = input.ReadString();
break;
}
+ case 90: {
+ DefaultValue = input.ReadString();
+ break;
+ }
}
}
}
@@ -674,7 +706,7 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class Types {
/// <summary>
- /// Kind represents a basic field type.
+ /// Basic field types.
/// </summary>
public enum Kind {
/// <summary>
@@ -718,7 +750,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// </summary>
TYPE_STRING = 9,
/// <summary>
- /// Field type group (deprecated proto2 type)
+ /// Field type group. Proto2 syntax only, and deprecated.
/// </summary>
TYPE_GROUP = 10,
/// <summary>
@@ -756,12 +788,11 @@ namespace Google.Protobuf.WellKnownTypes {
}
/// <summary>
- /// Cardinality represents whether a field is optional, required, or
- /// repeated.
+ /// Whether a field is optional, required, or repeated.
/// </summary>
public enum Cardinality {
/// <summary>
- /// The field cardinality is unknown. Typically an error condition.
+ /// For fields with unknown cardinality.
/// </summary>
CARDINALITY_UNKNOWN = 0,
/// <summary>
@@ -769,7 +800,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// </summary>
CARDINALITY_OPTIONAL = 1,
/// <summary>
- /// For required fields. Not used for proto3.
+ /// For required fields. Proto2 syntax only.
/// </summary>
CARDINALITY_REQUIRED = 2,
/// <summary>
@@ -848,7 +879,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// Proto options for the enum type.
+ /// Protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -1066,7 +1097,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// Proto options for the enum value.
+ /// Protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -1164,7 +1195,8 @@ namespace Google.Protobuf.WellKnownTypes {
}
/// <summary>
- /// Proto option attached to messages/fields/enums etc.
+ /// A protocol buffer option, which can be attached to a message, field,
+ /// enumeration, etc.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Option : pb::IMessage<Option> {
@@ -1198,7 +1230,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int NameFieldNumber = 1;
private string name_ = "";
/// <summary>
- /// Proto option name.
+ /// The option's name. For example, `"java_package"`.
/// </summary>
public string Name {
get { return name_; }
@@ -1211,7 +1243,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int ValueFieldNumber = 2;
private global::Google.Protobuf.WellKnownTypes.Any value_;
/// <summary>
- /// Proto option value.
+ /// The option's value. For example, `"com.google.protobuf"`.
/// </summary>
public global::Google.Protobuf.WellKnownTypes.Any Value {
get { return value_; }
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
index 43148772..a9d8e99c 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
@@ -29,9 +29,10 @@ namespace Google.Protobuf.WellKnownTypes {
"KAMiHAoLVUludDY0VmFsdWUSDQoFdmFsdWUYASABKAQiGwoKSW50MzJWYWx1",
"ZRINCgV2YWx1ZRgBIAEoBSIcCgtVSW50MzJWYWx1ZRINCgV2YWx1ZRgBIAEo",
"DSIaCglCb29sVmFsdWUSDQoFdmFsdWUYASABKAgiHAoLU3RyaW5nVmFsdWUS",
- "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJQ",
- "ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAGgAQGiAgNH",
- "UEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
+ "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJT",
+ "ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAGgAQH4AQGi",
+ "AgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3Rv",
+ "Mw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
diff --git a/m4/stl_hash.m4 b/m4/stl_hash.m4
index 0722b14a..d7def1af 100644
--- a/m4/stl_hash.m4
+++ b/m4/stl_hash.m4
@@ -4,8 +4,7 @@
# include AC_TRY_COMPILE for all the combinations we've seen in the
# wild. We define HASH_MAP_H to the location of the header file, and
# HASH_NAMESPACE to the namespace the class (unordered_map or
-# hash_map) is in. We define HAVE_UNORDERED_MAP if the class we found
-# is named unordered_map, or leave it undefined if not.
+# hash_map) is in.
# This also checks if unordered map exists.
AC_DEFUN([AC_CXX_STL_HASH],
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m
index 208cfe4e..fdb695ec 100644
--- a/objectivec/GPBMessage.m
+++ b/objectivec/GPBMessage.m
@@ -886,6 +886,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
- (void)dealloc {
[self internalClear:NO];
NSCAssert(!autocreator_, @"Autocreator was not cleared before dealloc.");
+ dispatch_release(readOnlySemaphore_);
[super dealloc];
}
diff --git a/objectivec/README.md b/objectivec/README.md
index 452feca4..c7313e4f 100644
--- a/objectivec/README.md
+++ b/objectivec/README.md
@@ -10,7 +10,7 @@ This directory contains the Objective C Protocol Buffers runtime library.
Requirements
------------
-The Objective C implemention requires:
+The Objective C implementation requires:
- Objective C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X).
- Xcode 7.0 (or later).
diff --git a/protoc-artifacts/README.md b/protoc-artifacts/README.md
index 06091cfe..4320f651 100644
--- a/protoc-artifacts/README.md
+++ b/protoc-artifacts/README.md
@@ -55,7 +55,7 @@ read [this page](http://central.sonatype.org/pages/apache-maven.html) on how to
configure GPG and Sonatype account.
You need to perform the deployment for every platform that you want to
-suppport. DO NOT close the staging repository until you have done the
+support. DO NOT close the staging repository until you have done the
deployment for all platforms. Currently the following platforms are supported:
- Linux (x86_32 and x86_64)
- Windows (x86_32 and x86_64) with
@@ -134,7 +134,7 @@ stored:
```
### Tested build environments
-We have succesfully built artifacts on the following environments:
+We have successfully built artifacts on the following environments:
- Linux x86_32 and x86_64:
- Centos 6.6 (within Docker 1.6.1)
- Ubuntu 14.04.2 64-bit
diff --git a/python/setup.py b/python/setup.py
index 1223775c..6ea3bad7 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -149,6 +149,10 @@ class build_py(_build_py):
class test_conformance(_build_py):
target = 'test_python'
def run(self):
+ if sys.version_info >= (2, 7):
+ # Python 2.6 dodges these extra failures.
+ os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = (
+ "--failure_list failure_list_python-post26.txt")
cmd = 'cd ../conformance && make %s' % (test_conformance.target)
status = subprocess.check_call(cmd, shell=True)
diff --git a/python/tox.ini b/python/tox.ini
index 301335bd..cf8d5401 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -15,10 +15,8 @@ commands =
cpp: python setup.py -q build --cpp_implementation --warnings_as_errors
python: python setup.py -q test -q
cpp: python setup.py -q test -q --cpp_implementation
-# TODO(xiaofeng): Disabled because the Python testee program crashes on
-# some conformance test inputs.
-# python: python setup.py -q test_conformance
-# cpp: python setup.py -q test_conformance --cpp_implementation
+ python: python setup.py -q test_conformance
+ cpp: python setup.py -q test_conformance --cpp_implementation
deps =
# Keep this list of dependencies in sync with setup.py.
six>=1.9
diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh
index 1b53dd78..75db7d93 100755
--- a/ruby/travis-test.sh
+++ b/ruby/travis-test.sh
@@ -17,11 +17,8 @@ test_version() {
"rvm install $version && rvm use $version && \
which ruby && \
gem install bundler && bundle && \
- rake test"
- # TODO(xiaofeng): Conformance tests are disabled because the ruby testee
- # program crashes on some inputs.
- # cd ../conformance && \
- # make test_ruby
+ rake test &&
+ cd ../conformance && make test_ruby"
fi
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc
index b493495d..15c68b3f 100644
--- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc
@@ -62,7 +62,6 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
descriptor_->message_type()->FindFieldByName("value");
variables_["key_type_name"] = type_name(key_descriptor);
variables_["value_type_name"] = type_name(value_descriptor);
- variables_["true_for_wrappers"] = IsWrapperType(value_descriptor) ? "true" : "";
scoped_ptr<FieldGeneratorBase> key_generator(CreateFieldGenerator(key_descriptor, 1));
scoped_ptr<FieldGeneratorBase> value_generator(CreateFieldGenerator(value_descriptor, 2));
@@ -76,7 +75,7 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
printer->Print(
variables_,
", $tag$);\n"
- "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>($true_for_wrappers$);\n");
+ "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>();\n");
WritePropertyDocComment(printer, descriptor_);
AddDeprecatedFlag(printer);
printer->Print(
diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h
index 1ba6ea7a..87271c5e 100644
--- a/src/google/protobuf/stubs/callback.h
+++ b/src/google/protobuf/stubs/callback.h
@@ -79,7 +79,7 @@ class LIBPROTOBUF_EXPORT Closure {
};
template<typename R>
-class LIBPROTOBUF_EXPORT ResultCallback {
+class ResultCallback {
public:
ResultCallback() {}
virtual ~ResultCallback() {}
diff --git a/travis.sh b/travis.sh
index 97a769d7..5a77a2a8 100755
--- a/travis.sh
+++ b/travis.sh
@@ -53,9 +53,7 @@ build_csharp() {
(cd csharp/src; mono ../../nuget.exe restore)
csharp/buildall.sh
- # TODO(xiaofeng): The conformance tests are disable because the testee program
- # crashes on some inputs.
- # cd conformance && make test_csharp && cd ..
+ cd conformance && make test_csharp && cd ..
}
build_golang() {