diff options
295 files changed, 22145 insertions, 23173 deletions
@@ -36,4 +36,9 @@ src/zcgunzip src/zcgzip src/.libs src/protoc +src/test_plugin +src/testzip.jar +src/testzip.list +src/testzip.proto +src/testzip.zip java/target/ diff --git a/CHANGES.txt b/CHANGES.txt index acd4d40..eebd57d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,13 +1,57 @@ -2009-11-18 version 2.2.0a: +2009-01-08 version 2.3.0: - There is probably no reason to install this release if you have arleady - installed 2.2.0. + General + * Parsers for repeated numeric fields now always accept both packed and + unpacked input. The [packed=true] option only affects serializers. + Therefore, it is possible to switch a field to packed format without + breaking backwards-compatibility -- as long as all parties are using + protobuf 2.3.0 or above, at least. + * The generic RPC service code generated by the C++, Java, and Python + generators can be disabled via file options: + option cc_generic_services = false; + option java_generic_services = false; + option py_generic_services = false; + This allows plugins to generate alternative code, possibly specific to some + particular RPC implementation. + + protoc + * Now supports a plugin system for code generators. Plugins can generate + code for new languages or inject additional code into the output of other + code generators. Plugins are just binaries which accept a protocol buffer + on stdin and write a protocol buffer to stdout, so they may be written in + any language. See src/google/protobuf/compiler/plugin.proto. + **WARNING**: Plugins are experimental. The interface may change in a + future version. + * If the output location ends in .zip or .jar, protoc will write its output + to a zip/jar archive instead of a directory. For example: + protoc --java_out=myproto_srcs.jar --python_out=myproto.zip myproto.proto + Currently the archive contents are not compressed, though this could change + in the future. + * inf, -inf, and nan can now be used as default values for float and double + fields. C++ - * Bumped binary interface version number, so that installing libprotobuf.so - v2.2.0 doesn't break already-compiled binaries that are linked against - v2.1.0. This should have happened as part of the original 2.2.0 release, - but somehow was missed. + * Various speed and code size optimizations. + * DynamicMessageFactory is now fully thread-safe. + * Message::Utf8DebugString() method is like DebugString() but avoids escaping + UTF-8 bytes. + * Compiled-in message types can now contain dynamic extensions, through use + of CodedInputStream::SetExtensionRegistry(). + * Now compiles shared libraries (DLLs) by default on Cygwin and MinGW, to + match other platforms. Use --disable-shared to avoid this. + + Java + * parseDelimitedFrom() and mergeDelimitedFrom() now detect EOF and return + false/null instead of throwing an exception. + * Fixed some initialization ordering bugs. + * Fixes for OpenJDK 7. + + Python + * 10-25 times faster than 2.2.0, still pure-Python. + * Calling a mutating method on a sub-message always instantiates the message + in its parent even if the mutating method doesn't actually mutate anything + (e.g. parsing from an empty string). + * Expanded descriptors a bit. 2009-08-11 version 2.2.0: diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index f9f2a6a..a20efc4 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -58,6 +58,7 @@ Patch contributors: * Slicing support for repeated scalar fields for the Python API. Oleg Smolsky <oleg.smolsky@gmail.com> * MS Visual Studio error format option. + * Detect unordered_map in stl_hash.m4. Brian Olson <brianolson@google.com> * gzip/zlib I/O support. Michael Poole <mdpoole@troilus.org> @@ -72,3 +73,12 @@ Patch contributors: * Emacs mode for Protocol Buffers (editors/protobuf-mode.el). Scott Stafford <scott.stafford@gmail.com> * Added Swap(), SwapElements(), and RemoveLast() to Reflection interface. + Alexander Melnikov <alm@sibmail.ru> + * HPUX support. + Oliver Jowett <oliver.jowett@gmail.com> + * Detect whether zlib is new enough in configure script. + * Fixes for Solaris 10 32/64-bit confusion. + Evan Jones <evanj@mit.edu> + * Optimize Java serialization code when writing a small message to a stream. + Michael Kucharski <m.kucharski@gmail.com> + * Added CodedInputStream.getTotalBytesRead(). diff --git a/Makefile.am b/Makefile.am index c311fe0..b65daee 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,6 +54,7 @@ EXTRA_DIST = \ vsprojects/protobuf.sln \ vsprojects/protoc.vcproj \ vsprojects/readme.txt \ + vsprojects/test_plugin.vcproj \ vsprojects/tests.vcproj \ vsprojects/lite-test.vcproj \ vsprojects/convert2008to2005.sh \ @@ -114,18 +115,12 @@ EXTRA_DIST = \ python/google/protobuf/internal/generator_test.py \ python/google/protobuf/internal/containers.py \ python/google/protobuf/internal/decoder.py \ - python/google/protobuf/internal/decoder_test.py \ python/google/protobuf/internal/descriptor_test.py \ python/google/protobuf/internal/encoder.py \ - python/google/protobuf/internal/encoder_test.py \ - python/google/protobuf/internal/input_stream.py \ - python/google/protobuf/internal/input_stream_test.py \ python/google/protobuf/internal/message_listener.py \ python/google/protobuf/internal/message_test.py \ python/google/protobuf/internal/more_extensions.proto \ python/google/protobuf/internal/more_messages.proto \ - python/google/protobuf/internal/output_stream.py \ - python/google/protobuf/internal/output_stream_test.py \ python/google/protobuf/internal/reflection_test.py \ python/google/protobuf/internal/service_reflection_test.py \ python/google/protobuf/internal/test_util.py \ diff --git a/Makefile.in b/Makefile.in index 0675d3e..22fd5ab 100644 --- a/Makefile.in +++ b/Makefile.in @@ -241,6 +241,7 @@ EXTRA_DIST = \ vsprojects/protobuf.sln \ vsprojects/protoc.vcproj \ vsprojects/readme.txt \ + vsprojects/test_plugin.vcproj \ vsprojects/tests.vcproj \ vsprojects/lite-test.vcproj \ vsprojects/convert2008to2005.sh \ @@ -301,18 +302,12 @@ EXTRA_DIST = \ python/google/protobuf/internal/generator_test.py \ python/google/protobuf/internal/containers.py \ python/google/protobuf/internal/decoder.py \ - python/google/protobuf/internal/decoder_test.py \ python/google/protobuf/internal/descriptor_test.py \ python/google/protobuf/internal/encoder.py \ - python/google/protobuf/internal/encoder_test.py \ - python/google/protobuf/internal/input_stream.py \ - python/google/protobuf/internal/input_stream_test.py \ python/google/protobuf/internal/message_listener.py \ python/google/protobuf/internal/message_test.py \ python/google/protobuf/internal/more_extensions.proto \ python/google/protobuf/internal/more_messages.proto \ - python/google/protobuf/internal/output_stream.py \ - python/google/protobuf/internal/output_stream_test.py \ python/google/protobuf/internal/reflection_test.py \ python/google/protobuf/internal/service_reflection_test.py \ python/google/protobuf/internal/test_util.py \ @@ -4,6 +4,8 @@ # be included in the distribution. These files are not checked in because they # are automatically generated. +set -e + # Check that we're being run from the right directory. if test ! -f src/google/protobuf/stubs/common.h; then cat >&2 << __EOF__ @@ -13,6 +15,14 @@ __EOF__ exit 1 fi +# Check that gtest is present. Usually it is already there since the +# directory is set up as an SVN external. +if test ! -e gtest; then + echo "Google Test not present. Fetching gtest-1.3.0 from the web..." + curl http://googletest.googlecode.com/files/gtest-1.3.0.tar.bz2 | tar jx + mv gtest-1.3.0 gtest +fi + set -ex # Temporary hack: Must change C runtime library to "multi-threaded DLL", diff --git a/config.h.in b/config.h.in index 1a44b91..4c6678d 100644 --- a/config.h.in +++ b/config.h.in @@ -1,11 +1,17 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* the name of <hash_set> */ +#undef HASH_MAP_CLASS + /* the location of <hash_map> */ #undef HASH_MAP_H /* the namespace of hash_map/hash_set */ #undef HASH_NAMESPACE +/* the name of <hash_set> */ +#undef HASH_SET_CLASS + /* the location of <hash_set> */ #undef HASH_SET_H @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for Protocol Buffers 2.2.0a. +# Generated by GNU Autoconf 2.61 for Protocol Buffers 2.3.0. # # Report bugs to <protobuf@googlegroups.com>. # @@ -723,8 +723,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='Protocol Buffers' PACKAGE_TARNAME='protobuf' -PACKAGE_VERSION='2.2.0a' -PACKAGE_STRING='Protocol Buffers 2.2.0a' +PACKAGE_VERSION='2.3.0' +PACKAGE_STRING='Protocol Buffers 2.3.0' PACKAGE_BUGREPORT='protobuf@googlegroups.com' ac_unique_file="src/google/protobuf/message.cc" @@ -1408,7 +1408,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Protocol Buffers 2.2.0a to adapt to many kinds of systems. +\`configure' configures Protocol Buffers 2.3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1479,7 +1479,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Protocol Buffers 2.2.0a:";; + short | recursive ) echo "Configuration of Protocol Buffers 2.3.0:";; esac cat <<\_ACEOF @@ -1583,7 +1583,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Protocol Buffers configure 2.2.0a +Protocol Buffers configure 2.3.0 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1597,7 +1597,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Protocol Buffers $as_me 2.2.0a, which was +It was created by Protocol Buffers $as_me 2.3.0, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2432,7 +2432,7 @@ fi # Define the identity of the package. PACKAGE='protobuf' - VERSION='2.2.0a' + VERSION='2.3.0' cat >>confdefs.h <<_ACEOF @@ -5191,7 +5191,7 @@ fi if test "$SUNCC" = "yes" -a "x${ac_cv_env_CXXFLAGS_set}" = "x"; then - CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -template=no%extdef ${CXXFLAGS}" + CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -library=Crun -template=no%extdef ${CXXFLAGS}" fi @@ -5256,13 +5256,6 @@ fi if test "x$ac_enable_64bit" = "xyes"; then - if test "x${ac_cv_env_LDFLAGS_set}" = "x"; then - - LDFLAGS="-L/usr/local/lib/${isainfo_k} ${LDFLAGS}" - -fi - - if test "x$libdir" = "x\${exec_prefix}/lib"; then libdir="${libdir}/${isainfo_k}" @@ -5270,7 +5263,7 @@ fi fi - if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then + if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then CXXFLAGS="${CXXFLAGS} -m64" ac_cv_env_CXXFLAGS_set=set @@ -5279,6 +5272,15 @@ fi fi + if test "x${ac_cv_env_CFLAGS_set}" = "x"; then + + CFLAGS="${CFLAGS} -m64" + ac_cv_env_CFLAGS_set=set + ac_cv_env_CFLAGS_value='-m64' + +fi + + if test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes" ; then CXXFLAGS="-xmemalign=8s ${CXXFLAGS}" @@ -5814,13 +5816,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:5817: $ac_compile\"" >&5) + (eval echo "\"\$as_me:5819: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:5820: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:5822: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:5823: output\"" >&5) + (eval echo "\"\$as_me:5825: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -6931,7 +6933,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6934 "configure"' > conftest.$ac_ext + echo '#line 6936 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -9012,11 +9014,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9015: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9017: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9019: \$? = $ac_status" >&5 + echo "$as_me:9021: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9336,11 +9338,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9339: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9341: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9343: \$? = $ac_status" >&5 + echo "$as_me:9345: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9441,11 +9443,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9444: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9446: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9448: \$? = $ac_status" >&5 + echo "$as_me:9450: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9496,11 +9498,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9499: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9501: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9503: \$? = $ac_status" >&5 + echo "$as_me:9505: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12244,7 +12246,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12247 "configure" +#line 12249 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12344,7 +12346,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12347 "configure" +#line 12349 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14347,11 +14349,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14350: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14352: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14354: \$? = $ac_status" >&5 + echo "$as_me:14356: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14446,11 +14448,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14449: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14451: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14453: \$? = $ac_status" >&5 + echo "$as_me:14455: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14498,11 +14500,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14501: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14503: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14505: \$? = $ac_status" >&5 + echo "$as_me:14507: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16238,9 +16240,57 @@ fi done +# Check for zlib. HAVE_ZLIB=0 if test "$with_zlib" != no; then - { echo "$as_me:$LINENO: checking for library containing zlibVersion" >&5 + + { echo "$as_me:$LINENO: checking zlib version" >&5 +echo $ECHO_N "checking zlib version... $ECHO_C" >&6; } + + # First check the zlib header version. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include <zlib.h> + #if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204) + # error zlib version too old + #endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + { echo "$as_me:$LINENO: result: ok (1.2.0.4 or later)" >&5 +echo "${ECHO_T}ok (1.2.0.4 or later)" >&6; } + + # Also need to add -lz to the linker flags and make sure this succeeds. + { echo "$as_me:$LINENO: checking for library containing zlibVersion" >&5 echo $ECHO_N "checking for library containing zlibVersion... $ECHO_C" >&6; } if test "${ac_cv_search_zlibVersion+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -16321,21 +16371,54 @@ ac_res=$ac_cv_search_zlibVersion if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + cat >>confdefs.h <<\_ACEOF #define HAVE_ZLIB 1 _ACEOF - HAVE_ZLIB=1 + HAVE_ZLIB=1 + else - if test "$with_zlib" != check; then - { { echo "$as_me:$LINENO: error: --with-zlib was given, but test for zlib failed + + if test "$with_zlib" != check; then + + { { echo "$as_me:$LINENO: error: --with-zlib was given, but no working zlib library was found See \`config.log' for more details." >&5 -echo "$as_me: error: --with-zlib was given, but test for zlib failed +echo "$as_me: error: --with-zlib was given, but no working zlib library was found See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } - fi + +fi + + +fi + + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + if test "$with_zlib" = check; then + + { echo "$as_me:$LINENO: result: headers missing or too old (requires 1.2.0.4)" >&5 +echo "${ECHO_T}headers missing or too old (requires 1.2.0.4)" >&6; } + +else + + { { echo "$as_me:$LINENO: error: --with-zlib was given, but zlib headers were not present or were too old (requires 1.2.0.4) +See \`config.log' for more details." >&5 +echo "$as_me: error: --with-zlib was given, but zlib headers were not present or were too old (requires 1.2.0.4) +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi if test $HAVE_ZLIB = 1; then @@ -17102,11 +17185,20 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - ac_cv_cxx_hash_map="" - for location in ext/hash_map hash_map; do - for namespace in __gnu_cxx "" std stdext; do - if test -z "$ac_cv_cxx_hash_map"; then - cat >conftest.$ac_ext <<_ACEOF + ac_cv_cxx_hash_map_header="" + ac_cv_cxx_hash_map_class="" + for location in tr1/unordered_map ext/hash_map hash_map; do + for namespace in std::tr1 __gnu_cxx "" std stdext; do + for name in unordered_map hash_map; do + + if test -z "$ac_cv_cxx_hash_map_header"; then + + # On OSX 1.5 / GCC 4.0.1 (the standard compiler on that platform), + # calling find() on a const unordered_map does not compile. So, we + # include a call to find() in our test to detect this broken + # implementation and avoid using it. Note that ext/hash_map works + # fine on this platform, so we'll end up using that. + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -17116,7 +17208,8 @@ cat >>conftest.$ac_ext <<_ACEOF int main () { -${namespace}::hash_map<int, int> t +const ${namespace}::$name<int, int> t; + t.find(1); ; return 0; } @@ -17138,8 +17231,9 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - ac_cv_cxx_hash_map="<$location>"; - ac_cv_cxx_hash_namespace="$namespace"; + ac_cv_cxx_hash_map_header="<$location>"; + ac_cv_cxx_hash_namespace="$namespace"; + ac_cv_cxx_hash_map_class="$name"; else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -17148,11 +17242,13 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi + fi + done done done - ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`; - if test -n "$ac_cv_cxx_hash_map"; then + ac_cv_cxx_hash_set_header=`echo "$ac_cv_cxx_hash_map_header" | sed s/map/set/`; + ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`; + if test -n "$ac_cv_cxx_hash_map_header"; then cat >>confdefs.h <<\_ACEOF #define HAVE_HASH_MAP 1 @@ -17165,12 +17261,22 @@ _ACEOF cat >>confdefs.h <<_ACEOF -#define HASH_MAP_H $ac_cv_cxx_hash_map +#define HASH_MAP_H $ac_cv_cxx_hash_map_header +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HASH_SET_H $ac_cv_cxx_hash_set_header +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define HASH_MAP_CLASS $ac_cv_cxx_hash_map_class _ACEOF cat >>confdefs.h <<_ACEOF -#define HASH_SET_H $ac_cv_cxx_hash_set +#define HASH_SET_CLASS $ac_cv_cxx_hash_set_class _ACEOF @@ -17178,8 +17284,8 @@ cat >>confdefs.h <<_ACEOF #define HASH_NAMESPACE $ac_cv_cxx_hash_namespace _ACEOF - { echo "$as_me:$LINENO: result: $ac_cv_cxx_hash_map" >&5 -echo "${ECHO_T}$ac_cv_cxx_hash_map" >&6; } + { echo "$as_me:$LINENO: result: $ac_cv_cxx_hash_map_header" >&5 +echo "${ECHO_T}$ac_cv_cxx_hash_map_header" >&6; } else { echo "$as_me:$LINENO: result: " >&5 echo "${ECHO_T}" >&6; } @@ -17188,8 +17294,10 @@ echo "$as_me: WARNING: could not find an STL hash_map" >&2;} fi -# HACK: Make gtest's configure script pick up our copy of CXXFLAGS, since the -# flags added by ACX_CHECK_SUNCC must be used when compiling gtest too. +# HACK: Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS, +# since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest +# too. +export CFLAGS export CXXFLAGS subdirs="$subdirs gtest" @@ -17641,7 +17749,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Protocol Buffers $as_me 2.2.0a, which was +This file was extended by Protocol Buffers $as_me 2.3.0, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17694,7 +17802,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -Protocol Buffers config.status 2.2.0a +Protocol Buffers config.status 2.3.0 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.ac b/configure.ac index 11ff427..63322b4 100644 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,7 @@ AC_PREREQ(2.59) # In the SVN trunk, the version should always be the next anticipated release # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # the size of one file name in the dist tarfile over the 99-char limit.) -AC_INIT([Protocol Buffers],[2.2.0a],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[2.3.0],[protobuf@googlegroups.com],[protobuf]) AC_CONFIG_SRCDIR(src/google/protobuf/message.cc) @@ -82,14 +82,38 @@ AC_FUNC_MEMCMP AC_FUNC_STRTOD AC_CHECK_FUNCS([ftruncate memset mkdir strchr strerror strtol]) +# Check for zlib. HAVE_ZLIB=0 -AS_IF([test "$with_zlib" != no], - [AC_SEARCH_LIBS([zlibVersion], [z], - [AC_DEFINE([HAVE_ZLIB], [1], [Enable classes using zlib compression.]) - HAVE_ZLIB=1], - [if test "$with_zlib" != check; then - AC_MSG_FAILURE([--with-zlib was given, but test for zlib failed]) - fi])]) +AS_IF([test "$with_zlib" != no], [ + AC_MSG_CHECKING([zlib version]) + + # First check the zlib header version. + AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([[ + #include <zlib.h> + #if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204) + # error zlib version too old + #endif + ]], []), [ + AC_MSG_RESULT([ok (1.2.0.4 or later)]) + + # Also need to add -lz to the linker flags and make sure this succeeds. + AC_SEARCH_LIBS([zlibVersion], [z], [ + AC_DEFINE([HAVE_ZLIB], [1], [Enable classes using zlib compression.]) + HAVE_ZLIB=1 + ], [ + AS_IF([test "$with_zlib" != check], [ + AC_MSG_FAILURE([--with-zlib was given, but no working zlib library was found]) + ]) + ]) + ], [ + AS_IF([test "$with_zlib" = check], [ + AC_MSG_RESULT([headers missing or too old (requires 1.2.0.4)]) + ], [ + AC_MSG_FAILURE([--with-zlib was given, but zlib headers were not present or were too old (requires 1.2.0.4)]) + ]) + ]) +]) AM_CONDITIONAL([HAVE_ZLIB], [test $HAVE_ZLIB = 1]) AS_IF([test "$with_protoc" != "no"], [ @@ -114,8 +138,10 @@ AM_CONDITIONAL([USE_EXTERNAL_PROTOC], [test "$with_protoc" != "no"]) ACX_PTHREAD AC_CXX_STL_HASH -# HACK: Make gtest's configure script pick up our copy of CXXFLAGS, since the -# flags added by ACX_CHECK_SUNCC must be used when compiling gtest too. +# HACK: Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS, +# since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest +# too. +export CFLAGS export CXXFLAGS AC_CONFIG_SUBDIRS([gtest]) diff --git a/editors/protobuf-mode.el b/editors/protobuf-mode.el index 3337c1f..09aecc9 100644 --- a/editors/protobuf-mode.el +++ b/editors/protobuf-mode.el @@ -71,7 +71,8 @@ ;; This mode does not inherit properties from other modes. So, we do not use ;; the usual `c-add-language' function. -(put 'protobuf-mode 'c-mode-prefix "protobuf-") +(eval-and-compile + (put 'protobuf-mode 'c-mode-prefix "protobuf-")) ;; The following code uses of the `c-lang-defconst' macro define syntactic ;; features of protocol buffer language. Refer to the documentation in the @@ -206,7 +207,8 @@ Key bindings: abbrev-mode t) (use-local-map protobuf-mode-map) (c-initialize-cc-mode t) - (c-make-emacs-variables-local) + (if (fboundp 'c-make-emacs-variables-local) + (c-make-emacs-variables-local)) (c-init-language-vars protobuf-mode) (c-common-init 'protobuf-mode) (easy-menu-add protobuf-menu) diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh index 69dd7da..07219dc 100755 --- a/generate_descriptor_proto.sh +++ b/generate_descriptor_proto.sh @@ -27,5 +27,7 @@ __EOF__ fi cd src -make $@ protoc && ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:. google/protobuf/descriptor.proto +make $@ protoc && + ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:. google/protobuf/descriptor.proto && \ + ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:. google/protobuf/compiler/plugin.proto cd .. diff --git a/gtest/CHANGES b/gtest/CHANGES index 3565588..1858f7f 100644 --- a/gtest/CHANGES +++ b/gtest/CHANGES @@ -1,3 +1,22 @@ +Changes for 1.4.0: + + * New feature: the event listener API + * New feature: test shuffling + * New feature: the XML report format is closer to junitreport and can + be parsed by Hudson now. + * New feature: when a test runs under Visual Studio, its failures are + integrated in the IDE. + * New feature: /MD(d) versions of VC++ projects. + * New feature: elapsed time for the tests is printed by default. + * New feature: comes with a TR1 tuple implementation such that Boost + is no longer needed for Combine(). + * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. + * New feature: the Xcode project can now produce static gtest + libraries in addition to a framework. + * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, + Symbian, gcc, and C++Builder. + * Bug fixes and implementation clean-ups. + Changes for 1.3.0: * New feature: death tests on Windows, Cygwin, and Mac. @@ -11,7 +30,7 @@ Changes for 1.3.0: .cc file for easy deployment. * New feature: support for distributing test functions to multiple machines (requires support from the test runner). - * Bug fixes and implementation clean-up. + * Bug fixes and implementation clean-ups. Changes for 1.2.1: diff --git a/gtest/CONTRIBUTORS b/gtest/CONTRIBUTORS index ae91217..40ce6c8 100644 --- a/gtest/CONTRIBUTORS +++ b/gtest/CONTRIBUTORS @@ -21,7 +21,7 @@ Mika Raento <mikie@iki.fi> Patrick Hanna <phanna@google.com> Patrick Riley <pfr@google.com> Peter Kaminski <piotrk@google.com> -Preston Jackson <preston.jackson@gmail.com> +Preston Jackson <preston.a.jackson@gmail.com> Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com> Russ Cox <rsc@google.com> Russ Rufer <russ@pentad.com> diff --git a/gtest/Makefile.am b/gtest/Makefile.am index 2f7e911..3a9233d 100644 --- a/gtest/Makefile.am +++ b/gtest/Makefile.am @@ -12,6 +12,8 @@ EXTRA_DIST = \ include/gtest/internal/gtest-param-util-generated.h.pump \ make/Makefile \ scons/SConscript \ + scons/SConstruct \ + scons/SConstruct.common \ scripts/fuse_gtest_files.py \ scripts/gen_gtest_pred_impl.py \ scripts/test/Makefile \ @@ -19,15 +21,15 @@ EXTRA_DIST = \ # MSVC project files EXTRA_DIST += \ + msvc/gtest-md.sln \ msvc/gtest.sln \ + msvc/gtest-md.vcproj \ msvc/gtest.vcproj \ - msvc/gtest_color_test_.vcproj \ - msvc/gtest_env_var_test_.vcproj \ - msvc/gtest_environment_test.vcproj \ + msvc/gtest_main-md.vcproj \ msvc/gtest_main.vcproj \ - msvc/gtest_output_test_.vcproj \ + msvc/gtest_prod_test-md.vcproj \ msvc/gtest_prod_test.vcproj \ - msvc/gtest_uninitialized_test_.vcproj \ + msvc/gtest_unittest-md.vcproj \ msvc/gtest_unittest.vcproj # xcode project files @@ -36,9 +38,8 @@ EXTRA_DIST += \ xcode/Config/FrameworkTarget.xcconfig \ xcode/Config/General.xcconfig \ xcode/Config/ReleaseProject.xcconfig \ + xcode/Config/StaticLibraryTarget.xcconfig \ xcode/Config/TestTarget.xcconfig \ - xcode/Config/InternalTestTarget.xcconfig \ - xcode/Config/InternalPythonTestTarget.xcconfig \ xcode/Resources/Info.plist \ xcode/Scripts/versiongenerate.py \ xcode/Scripts/runtests.sh \ @@ -172,22 +173,29 @@ TESTS += samples/sample6_unittest check_PROGRAMS += samples/sample6_unittest samples_sample6_unittest_SOURCES = samples/prime_tables.h \ samples/sample6_unittest.cc -samples_sample6_unittest_LDADD = lib/libgtest_main.la \ - samples/libsamples.la +samples_sample6_unittest_LDADD = lib/libgtest_main.la TESTS += samples/sample7_unittest check_PROGRAMS += samples/sample7_unittest samples_sample7_unittest_SOURCES = samples/prime_tables.h \ samples/sample7_unittest.cc -samples_sample7_unittest_LDADD = lib/libgtest_main.la \ - samples/libsamples.la +samples_sample7_unittest_LDADD = lib/libgtest_main.la TESTS += samples/sample8_unittest check_PROGRAMS += samples/sample8_unittest samples_sample8_unittest_SOURCES = samples/prime_tables.h \ samples/sample8_unittest.cc -samples_sample8_unittest_LDADD = lib/libgtest_main.la \ - samples/libsamples.la +samples_sample8_unittest_LDADD = lib/libgtest_main.la + +TESTS += samples/sample9_unittest +check_PROGRAMS += samples/sample9_unittest +samples_sample9_unittest_SOURCES = samples/sample9_unittest.cc +samples_sample9_unittest_LDADD = lib/libgtest.la + +TESTS += samples/sample10_unittest +check_PROGRAMS += samples/sample10_unittest +samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc +samples_sample10_unittest_LDADD = lib/libgtest.la TESTS += test/gtest-death-test_test check_PROGRAMS += test/gtest-death-test_test @@ -299,6 +307,11 @@ check_PROGRAMS += test/gtest-unittest-api_test test_gtest_unittest_api_test_SOURCES = test/gtest-unittest-api_test.cc test_gtest_unittest_api_test_LDADD = lib/libgtest_main.la +TESTS += test/gtest-listener_test +check_PROGRAMS += test/gtest-listener_test +test_gtest_listener_test_SOURCES = test/gtest-listener_test.cc +test_gtest_listener_test_LDADD = lib/libgtest_main.la + # Verifies that Google Test works when RTTI is disabled. TESTS += test/gtest_no_rtti_test check_PROGRAMS += test/gtest_no_rtti_test @@ -382,6 +395,12 @@ EXTRA_DIST += test/gtest_output_test_golden_lin.txt \ test/gtest_output_test_golden_win.txt TESTS += test/gtest_output_test.py +check_PROGRAMS += test/gtest_shuffle_test_ +test_gtest_shuffle_test__SOURCES = test/gtest_shuffle_test_.cc +test_gtest_shuffle_test__LDADD = lib/libgtest.la +check_SCRIPTS += test/gtest_shuffle_test.py +TESTS += test/gtest_shuffle_test.py + check_PROGRAMS += test/gtest_throw_on_failure_test_ test_gtest_throw_on_failure_test__SOURCES = \ test/gtest_throw_on_failure_test_.cc \ @@ -407,7 +426,7 @@ TESTS += test/gtest_xml_outfiles_test.py check_PROGRAMS += test/gtest_xml_output_unittest_ test_gtest_xml_output_unittest__SOURCES = test/gtest_xml_output_unittest_.cc -test_gtest_xml_output_unittest__LDADD = lib/libgtest_main.la +test_gtest_xml_output_unittest__LDADD = lib/libgtest.la check_SCRIPTS += test/gtest_xml_output_unittest.py TESTS += test/gtest_xml_output_unittest.py diff --git a/gtest/Makefile.in b/gtest/Makefile.in index 678d069..2cc34bf 100644 --- a/gtest/Makefile.in +++ b/gtest/Makefile.in @@ -47,6 +47,8 @@ TESTS = samples/sample1_unittest$(EXEEXT) \ samples/sample6_unittest$(EXEEXT) \ samples/sample7_unittest$(EXEEXT) \ samples/sample8_unittest$(EXEEXT) \ + samples/sample9_unittest$(EXEEXT) \ + samples/sample10_unittest$(EXEEXT) \ test/gtest-death-test_test$(EXEEXT) \ test/gtest_environment_test$(EXEEXT) \ test/gtest-filepath_test$(EXEEXT) \ @@ -66,6 +68,7 @@ TESTS = samples/sample1_unittest$(EXEEXT) \ test/gtest-typed-test_test$(EXEEXT) \ test/gtest_unittest$(EXEEXT) \ test/gtest-unittest-api_test$(EXEEXT) \ + test/gtest-listener_test$(EXEEXT) \ test/gtest_no_rtti_test$(EXEEXT) \ test/gtest-tuple_test$(EXEEXT) \ test/gtest_use_own_tuple_test$(EXEEXT) $(am__append_2) @@ -77,6 +80,8 @@ check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \ samples/sample6_unittest$(EXEEXT) \ samples/sample7_unittest$(EXEEXT) \ samples/sample8_unittest$(EXEEXT) \ + samples/sample9_unittest$(EXEEXT) \ + samples/sample10_unittest$(EXEEXT) \ test/gtest-death-test_test$(EXEEXT) \ test/gtest_environment_test$(EXEEXT) \ test/gtest-filepath_test$(EXEEXT) \ @@ -96,6 +101,7 @@ check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \ test/gtest-typed-test_test$(EXEEXT) \ test/gtest_unittest$(EXEEXT) \ test/gtest-unittest-api_test$(EXEEXT) \ + test/gtest-listener_test$(EXEEXT) \ test/gtest_no_rtti_test$(EXEEXT) \ test/gtest-tuple_test$(EXEEXT) \ test/gtest_use_own_tuple_test$(EXEEXT) $(am__EXEEXT_1) @@ -107,6 +113,7 @@ check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_help_test_ \ @HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest_ \ @HAVE_PYTHON_TRUE@ test/gtest_output_test_ \ +@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test_ \ @HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test_ \ @HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test_ \ @HAVE_PYTHON_TRUE@ test/gtest_xml_outfile1_test_ \ @@ -120,6 +127,7 @@ check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_help_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest.py \ @HAVE_PYTHON_TRUE@ test/gtest_output_test.py \ +@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_xml_outfiles_test.py \ @@ -183,11 +191,17 @@ samples_libsamples_la_OBJECTS = $(am_samples_libsamples_la_OBJECTS) @HAVE_PYTHON_TRUE@ test/gtest_help_test_$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest_$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_output_test_$(EXEEXT) \ +@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test_$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test_$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test_$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_xml_outfile1_test_$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_xml_outfile2_test_$(EXEEXT) \ @HAVE_PYTHON_TRUE@ test/gtest_xml_output_unittest_$(EXEEXT) +am_samples_sample10_unittest_OBJECTS = \ + samples/sample10_unittest.$(OBJEXT) +samples_sample10_unittest_OBJECTS = \ + $(am_samples_sample10_unittest_OBJECTS) +samples_sample10_unittest_DEPENDENCIES = lib/libgtest.la am_samples_sample1_unittest_OBJECTS = \ samples/sample1_unittest.$(OBJEXT) samples_sample1_unittest_OBJECTS = \ @@ -222,20 +236,22 @@ am_samples_sample6_unittest_OBJECTS = \ samples/sample6_unittest.$(OBJEXT) samples_sample6_unittest_OBJECTS = \ $(am_samples_sample6_unittest_OBJECTS) -samples_sample6_unittest_DEPENDENCIES = lib/libgtest_main.la \ - samples/libsamples.la +samples_sample6_unittest_DEPENDENCIES = lib/libgtest_main.la am_samples_sample7_unittest_OBJECTS = \ samples/sample7_unittest.$(OBJEXT) samples_sample7_unittest_OBJECTS = \ $(am_samples_sample7_unittest_OBJECTS) -samples_sample7_unittest_DEPENDENCIES = lib/libgtest_main.la \ - samples/libsamples.la +samples_sample7_unittest_DEPENDENCIES = lib/libgtest_main.la am_samples_sample8_unittest_OBJECTS = \ samples/sample8_unittest.$(OBJEXT) samples_sample8_unittest_OBJECTS = \ $(am_samples_sample8_unittest_OBJECTS) -samples_sample8_unittest_DEPENDENCIES = lib/libgtest_main.la \ - samples/libsamples.la +samples_sample8_unittest_DEPENDENCIES = lib/libgtest_main.la +am_samples_sample9_unittest_OBJECTS = \ + samples/sample9_unittest.$(OBJEXT) +samples_sample9_unittest_OBJECTS = \ + $(am_samples_sample9_unittest_OBJECTS) +samples_sample9_unittest_DEPENDENCIES = lib/libgtest.la am_test_gtest_death_test_test_OBJECTS = test/test_gtest_death_test_test-gtest-death-test_test.$(OBJEXT) test_gtest_death_test_test_OBJECTS = \ $(am_test_gtest_death_test_test_OBJECTS) @@ -256,6 +272,11 @@ am_test_gtest_linked_ptr_test_OBJECTS = \ test_gtest_linked_ptr_test_OBJECTS = \ $(am_test_gtest_linked_ptr_test_OBJECTS) test_gtest_linked_ptr_test_DEPENDENCIES = lib/libgtest_main.la +am_test_gtest_listener_test_OBJECTS = \ + test/gtest-listener_test.$(OBJEXT) +test_gtest_listener_test_OBJECTS = \ + $(am_test_gtest_listener_test_OBJECTS) +test_gtest_listener_test_DEPENDENCIES = lib/libgtest_main.la am_test_gtest_message_test_OBJECTS = \ test/gtest-message_test.$(OBJEXT) test_gtest_message_test_OBJECTS = \ @@ -389,6 +410,14 @@ test_gtest_prod_test_DEPENDENCIES = lib/libgtest_main.la am_test_gtest_repeat_test_OBJECTS = test/gtest_repeat_test.$(OBJEXT) test_gtest_repeat_test_OBJECTS = $(am_test_gtest_repeat_test_OBJECTS) test_gtest_repeat_test_DEPENDENCIES = lib/libgtest.la +am__test_gtest_shuffle_test__SOURCES_DIST = \ + test/gtest_shuffle_test_.cc +@HAVE_PYTHON_TRUE@am_test_gtest_shuffle_test__OBJECTS = \ +@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test_.$(OBJEXT) +test_gtest_shuffle_test__OBJECTS = \ + $(am_test_gtest_shuffle_test__OBJECTS) +@HAVE_PYTHON_TRUE@test_gtest_shuffle_test__DEPENDENCIES = \ +@HAVE_PYTHON_TRUE@ lib/libgtest.la am_test_gtest_sole_header_test_OBJECTS = \ test/gtest_sole_header_test.$(OBJEXT) test_gtest_sole_header_test_OBJECTS = \ @@ -461,7 +490,7 @@ am__test_gtest_xml_output_unittest__SOURCES_DIST = \ test_gtest_xml_output_unittest__OBJECTS = \ $(am_test_gtest_xml_output_unittest__OBJECTS) @HAVE_PYTHON_TRUE@test_gtest_xml_output_unittest__DEPENDENCIES = \ -@HAVE_PYTHON_TRUE@ lib/libgtest_main.la +@HAVE_PYTHON_TRUE@ lib/libgtest.la binSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(bin_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/build-aux @@ -487,6 +516,7 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \ $(samples_libsamples_la_SOURCES) \ + $(samples_sample10_unittest_SOURCES) \ $(samples_sample1_unittest_SOURCES) \ $(samples_sample2_unittest_SOURCES) \ $(samples_sample3_unittest_SOURCES) \ @@ -495,9 +525,11 @@ SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \ $(samples_sample6_unittest_SOURCES) \ $(samples_sample7_unittest_SOURCES) \ $(samples_sample8_unittest_SOURCES) \ + $(samples_sample9_unittest_SOURCES) \ $(test_gtest_death_test_test_SOURCES) \ $(test_gtest_filepath_test_SOURCES) \ $(test_gtest_linked_ptr_test_SOURCES) \ + $(test_gtest_listener_test_SOURCES) \ $(test_gtest_message_test_SOURCES) \ $(test_gtest_options_test_SOURCES) \ $(test_gtest_param_test_test_SOURCES) \ @@ -520,6 +552,7 @@ SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \ $(test_gtest_pred_impl_unittest_SOURCES) \ $(test_gtest_prod_test_SOURCES) \ $(test_gtest_repeat_test_SOURCES) \ + $(test_gtest_shuffle_test__SOURCES) \ $(test_gtest_sole_header_test_SOURCES) \ $(test_gtest_stress_test_SOURCES) \ $(test_gtest_throw_on_failure_ex_test_SOURCES) \ @@ -533,6 +566,7 @@ SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \ DIST_SOURCES = $(lib_libgtest_la_SOURCES) \ $(lib_libgtest_main_la_SOURCES) \ $(samples_libsamples_la_SOURCES) \ + $(samples_sample10_unittest_SOURCES) \ $(samples_sample1_unittest_SOURCES) \ $(samples_sample2_unittest_SOURCES) \ $(samples_sample3_unittest_SOURCES) \ @@ -541,9 +575,11 @@ DIST_SOURCES = $(lib_libgtest_la_SOURCES) \ $(samples_sample6_unittest_SOURCES) \ $(samples_sample7_unittest_SOURCES) \ $(samples_sample8_unittest_SOURCES) \ + $(samples_sample9_unittest_SOURCES) \ $(test_gtest_death_test_test_SOURCES) \ $(test_gtest_filepath_test_SOURCES) \ $(test_gtest_linked_ptr_test_SOURCES) \ + $(test_gtest_listener_test_SOURCES) \ $(test_gtest_message_test_SOURCES) \ $(test_gtest_options_test_SOURCES) \ $(test_gtest_param_test_test_SOURCES) \ @@ -566,6 +602,7 @@ DIST_SOURCES = $(lib_libgtest_la_SOURCES) \ $(test_gtest_pred_impl_unittest_SOURCES) \ $(test_gtest_prod_test_SOURCES) \ $(test_gtest_repeat_test_SOURCES) \ + $(am__test_gtest_shuffle_test__SOURCES_DIST) \ $(test_gtest_sole_header_test_SOURCES) \ $(test_gtest_stress_test_SOURCES) \ $(test_gtest_throw_on_failure_ex_test_SOURCES) \ @@ -727,22 +764,21 @@ EXTRA_DIST = CHANGES CONTRIBUTORS \ include/gtest/internal/gtest-tuple.h.pump \ include/gtest/internal/gtest-type-util.h.pump \ include/gtest/internal/gtest-param-util-generated.h.pump \ - make/Makefile scons/SConscript scripts/fuse_gtest_files.py \ + make/Makefile scons/SConscript scons/SConstruct \ + scons/SConstruct.common scripts/fuse_gtest_files.py \ scripts/gen_gtest_pred_impl.py scripts/test/Makefile \ - test/gtest_all_test.cc msvc/gtest.sln msvc/gtest.vcproj \ - msvc/gtest_color_test_.vcproj msvc/gtest_env_var_test_.vcproj \ - msvc/gtest_environment_test.vcproj msvc/gtest_main.vcproj \ - msvc/gtest_output_test_.vcproj msvc/gtest_prod_test.vcproj \ - msvc/gtest_uninitialized_test_.vcproj \ - msvc/gtest_unittest.vcproj xcode/Config/DebugProject.xcconfig \ + test/gtest_all_test.cc msvc/gtest-md.sln msvc/gtest.sln \ + msvc/gtest-md.vcproj msvc/gtest.vcproj \ + msvc/gtest_main-md.vcproj msvc/gtest_main.vcproj \ + msvc/gtest_prod_test-md.vcproj msvc/gtest_prod_test.vcproj \ + msvc/gtest_unittest-md.vcproj msvc/gtest_unittest.vcproj \ + xcode/Config/DebugProject.xcconfig \ xcode/Config/FrameworkTarget.xcconfig \ xcode/Config/General.xcconfig \ xcode/Config/ReleaseProject.xcconfig \ - xcode/Config/TestTarget.xcconfig \ - xcode/Config/InternalTestTarget.xcconfig \ - xcode/Config/InternalPythonTestTarget.xcconfig \ - xcode/Resources/Info.plist xcode/Scripts/versiongenerate.py \ - xcode/Scripts/runtests.sh \ + xcode/Config/StaticLibraryTarget.xcconfig \ + xcode/Config/TestTarget.xcconfig xcode/Resources/Info.plist \ + xcode/Scripts/versiongenerate.py xcode/Scripts/runtests.sh \ xcode/gtest.xcodeproj/project.pbxproj \ xcode/Samples/FrameworkSample/Info.plist \ xcode/Samples/FrameworkSample/widget_test.cc \ @@ -848,21 +884,19 @@ samples_sample5_unittest_LDADD = lib/libgtest_main.la \ samples_sample6_unittest_SOURCES = samples/prime_tables.h \ samples/sample6_unittest.cc -samples_sample6_unittest_LDADD = lib/libgtest_main.la \ - samples/libsamples.la - +samples_sample6_unittest_LDADD = lib/libgtest_main.la samples_sample7_unittest_SOURCES = samples/prime_tables.h \ samples/sample7_unittest.cc -samples_sample7_unittest_LDADD = lib/libgtest_main.la \ - samples/libsamples.la - +samples_sample7_unittest_LDADD = lib/libgtest_main.la samples_sample8_unittest_SOURCES = samples/prime_tables.h \ samples/sample8_unittest.cc -samples_sample8_unittest_LDADD = lib/libgtest_main.la \ - samples/libsamples.la - +samples_sample8_unittest_LDADD = lib/libgtest_main.la +samples_sample9_unittest_SOURCES = samples/sample9_unittest.cc +samples_sample9_unittest_LDADD = lib/libgtest.la +samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc +samples_sample10_unittest_LDADD = lib/libgtest.la test_gtest_death_test_test_SOURCES = test/gtest-death-test_test.cc test_gtest_death_test_test_CXXFLAGS = $(AM_CXXFLAGS) $(PTHREAD_CFLAGS) test_gtest_death_test_test_LDADD = $(PTHREAD_LIBS) $(PTHREAD_CFLAGS) \ @@ -918,6 +952,8 @@ test_gtest_unittest_SOURCES = test/gtest_unittest.cc test_gtest_unittest_LDADD = lib/libgtest_main.la test_gtest_unittest_api_test_SOURCES = test/gtest-unittest-api_test.cc test_gtest_unittest_api_test_LDADD = lib/libgtest_main.la +test_gtest_listener_test_SOURCES = test/gtest-listener_test.cc +test_gtest_listener_test_LDADD = lib/libgtest_main.la test_gtest_no_rtti_test_SOURCES = test/gtest_unittest.cc \ src/gtest-all.cc \ src/gtest_main.cc @@ -953,6 +989,7 @@ test_gtest_use_own_tuple_test_CXXFLAGS = \ @HAVE_PYTHON_TRUE@ test/gtest_help_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_list_tests_unittest.py \ @HAVE_PYTHON_TRUE@ test/gtest_output_test.py \ +@HAVE_PYTHON_TRUE@ test/gtest_shuffle_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_uninitialized_test.py \ @HAVE_PYTHON_TRUE@ test/gtest_xml_outfiles_test.py \ @@ -973,6 +1010,8 @@ test_gtest_use_own_tuple_test_CXXFLAGS = \ @HAVE_PYTHON_TRUE@test_gtest_list_tests_unittest__LDADD = lib/libgtest.la @HAVE_PYTHON_TRUE@test_gtest_output_test__SOURCES = test/gtest_output_test_.cc @HAVE_PYTHON_TRUE@test_gtest_output_test__LDADD = lib/libgtest.la +@HAVE_PYTHON_TRUE@test_gtest_shuffle_test__SOURCES = test/gtest_shuffle_test_.cc +@HAVE_PYTHON_TRUE@test_gtest_shuffle_test__LDADD = lib/libgtest.la @HAVE_PYTHON_TRUE@test_gtest_throw_on_failure_test__SOURCES = \ @HAVE_PYTHON_TRUE@ test/gtest_throw_on_failure_test_.cc \ @HAVE_PYTHON_TRUE@ src/gtest-all.cc @@ -985,7 +1024,7 @@ test_gtest_use_own_tuple_test_CXXFLAGS = \ @HAVE_PYTHON_TRUE@test_gtest_xml_outfile2_test__SOURCES = test/gtest_xml_outfile2_test_.cc @HAVE_PYTHON_TRUE@test_gtest_xml_outfile2_test__LDADD = lib/libgtest_main.la @HAVE_PYTHON_TRUE@test_gtest_xml_output_unittest__SOURCES = test/gtest_xml_output_unittest_.cc -@HAVE_PYTHON_TRUE@test_gtest_xml_output_unittest__LDADD = lib/libgtest_main.la +@HAVE_PYTHON_TRUE@test_gtest_xml_output_unittest__LDADD = lib/libgtest.la all: all-am .SUFFIXES: @@ -1123,6 +1162,11 @@ clean-checkPROGRAMS: echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done +samples/sample10_unittest.$(OBJEXT): samples/$(am__dirstamp) \ + samples/$(DEPDIR)/$(am__dirstamp) +samples/sample10_unittest$(EXEEXT): $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_DEPENDENCIES) samples/$(am__dirstamp) + @rm -f samples/sample10_unittest$(EXEEXT) + $(CXXLINK) $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_LDADD) $(LIBS) samples/sample1_unittest.$(OBJEXT): samples/$(am__dirstamp) \ samples/$(DEPDIR)/$(am__dirstamp) samples/sample1_unittest$(EXEEXT): $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_DEPENDENCIES) samples/$(am__dirstamp) @@ -1163,6 +1207,11 @@ samples/sample8_unittest.$(OBJEXT): samples/$(am__dirstamp) \ samples/sample8_unittest$(EXEEXT): $(samples_sample8_unittest_OBJECTS) $(samples_sample8_unittest_DEPENDENCIES) samples/$(am__dirstamp) @rm -f samples/sample8_unittest$(EXEEXT) $(CXXLINK) $(samples_sample8_unittest_OBJECTS) $(samples_sample8_unittest_LDADD) $(LIBS) +samples/sample9_unittest.$(OBJEXT): samples/$(am__dirstamp) \ + samples/$(DEPDIR)/$(am__dirstamp) +samples/sample9_unittest$(EXEEXT): $(samples_sample9_unittest_OBJECTS) $(samples_sample9_unittest_DEPENDENCIES) samples/$(am__dirstamp) + @rm -f samples/sample9_unittest$(EXEEXT) + $(CXXLINK) $(samples_sample9_unittest_OBJECTS) $(samples_sample9_unittest_LDADD) $(LIBS) test/$(am__dirstamp): @$(MKDIR_P) test @: > test/$(am__dirstamp) @@ -1184,6 +1233,11 @@ test/gtest-linked_ptr_test.$(OBJEXT): test/$(am__dirstamp) \ test/gtest-linked_ptr_test$(EXEEXT): $(test_gtest_linked_ptr_test_OBJECTS) $(test_gtest_linked_ptr_test_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/gtest-linked_ptr_test$(EXEEXT) $(CXXLINK) $(test_gtest_linked_ptr_test_OBJECTS) $(test_gtest_linked_ptr_test_LDADD) $(LIBS) +test/gtest-listener_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/gtest-listener_test$(EXEEXT): $(test_gtest_listener_test_OBJECTS) $(test_gtest_listener_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/gtest-listener_test$(EXEEXT) + $(CXXLINK) $(test_gtest_listener_test_OBJECTS) $(test_gtest_listener_test_LDADD) $(LIBS) test/gtest-message_test.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/gtest-message_test$(EXEEXT): $(test_gtest_message_test_OBJECTS) $(test_gtest_message_test_DEPENDENCIES) test/$(am__dirstamp) @@ -1308,6 +1362,11 @@ test/gtest_repeat_test.$(OBJEXT): test/$(am__dirstamp) \ test/gtest_repeat_test$(EXEEXT): $(test_gtest_repeat_test_OBJECTS) $(test_gtest_repeat_test_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/gtest_repeat_test$(EXEEXT) $(CXXLINK) $(test_gtest_repeat_test_OBJECTS) $(test_gtest_repeat_test_LDADD) $(LIBS) +test/gtest_shuffle_test_.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/gtest_shuffle_test_$(EXEEXT): $(test_gtest_shuffle_test__OBJECTS) $(test_gtest_shuffle_test__DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/gtest_shuffle_test_$(EXEEXT) + $(CXXLINK) $(test_gtest_shuffle_test__OBJECTS) $(test_gtest_shuffle_test__LDADD) $(LIBS) test/gtest_sole_header_test.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/gtest_sole_header_test$(EXEEXT): $(test_gtest_sole_header_test_OBJECTS) $(test_gtest_sole_header_test_DEPENDENCIES) test/$(am__dirstamp) @@ -1390,6 +1449,7 @@ mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f samples/sample1.$(OBJEXT) -rm -f samples/sample1.lo + -rm -f samples/sample10_unittest.$(OBJEXT) -rm -f samples/sample1_unittest.$(OBJEXT) -rm -f samples/sample2.$(OBJEXT) -rm -f samples/sample2.lo @@ -1402,6 +1462,7 @@ mostlyclean-compile: -rm -f samples/sample6_unittest.$(OBJEXT) -rm -f samples/sample7_unittest.$(OBJEXT) -rm -f samples/sample8_unittest.$(OBJEXT) + -rm -f samples/sample9_unittest.$(OBJEXT) -rm -f src/gtest-death-test.$(OBJEXT) -rm -f src/gtest-death-test.lo -rm -f src/gtest-filepath.$(OBJEXT) @@ -1425,6 +1486,7 @@ mostlyclean-compile: -rm -f src/test_gtest_use_own_tuple_test-gtest-all.$(OBJEXT) -rm -f test/gtest-filepath_test.$(OBJEXT) -rm -f test/gtest-linked_ptr_test.$(OBJEXT) + -rm -f test/gtest-listener_test.$(OBJEXT) -rm -f test/gtest-message_test.$(OBJEXT) -rm -f test/gtest-options_test.$(OBJEXT) -rm -f test/gtest-param-test2_test.$(OBJEXT) @@ -1447,6 +1509,7 @@ mostlyclean-compile: -rm -f test/gtest_pred_impl_unittest.$(OBJEXT) -rm -f test/gtest_prod_test.$(OBJEXT) -rm -f test/gtest_repeat_test.$(OBJEXT) + -rm -f test/gtest_shuffle_test_.$(OBJEXT) -rm -f test/gtest_sole_header_test.$(OBJEXT) -rm -f test/gtest_stress_test.$(OBJEXT) -rm -f test/gtest_uninitialized_test_.$(OBJEXT) @@ -1467,6 +1530,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample10_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample2_unittest.Po@am__quote@ @@ -1477,6 +1541,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample6_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample7_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample8_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample9_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-death-test.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-filepath.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-port.Plo@am__quote@ @@ -1493,6 +1558,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_gtest_use_own_tuple_test-gtest-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-filepath_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-linked_ptr_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-listener_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-message_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-options_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest-param-test2_test.Po@am__quote@ @@ -1515,6 +1581,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_pred_impl_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_prod_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_repeat_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_shuffle_test_.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_sole_header_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_stress_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_uninitialized_test_.Po@am__quote@ diff --git a/gtest/README b/gtest/README index cb8d4de..a9172c5 100644 --- a/gtest/README +++ b/gtest/README @@ -190,9 +190,16 @@ see 'gtest-config --help' for more detailed information. g++ $(../../my_gtest_build/scripts/gtest-config ...) ... ### Windows ### -Open the gtest.sln file in the msvc/ folder using Visual Studio, and -you are ready to build Google Test the same way you build any Visual -Studio project. +The msvc\ folder contains two solutions with Visual C++ projects. Open the +gtest.sln or gtest-md.sln file using Visual Studio, and you are ready to +build Google Test the same way you build any Visual Studio project. Files +that have names ending with -md use DLL versions of Microsoft runtime +libraries (the /MD or the /MDd compiler option). Files without that suffix +use static versions of the runtime libraries (the /MT or the /MTd option). +Please note that one must use the same option to compile both gtest and his +test code. If you use Visual Studio 2005 or above, we recommend the -md +version as /MD is the default for new projects in these versions of Visual +Studio. ### Mac OS X (universal-binary framework) ### Open the gtest.xcodeproj in the xcode/ folder using Xcode. Build the "gtest" @@ -201,10 +208,10 @@ directory (selected in the Xcode "Preferences..." -> "Building" pane and defaults to xcode/build). Alternatively, at the command line, enter: xcodebuild - -This will build the "Release" configuration of the gtest.framework, but you can -select the "Debug" configuration with a command line option. See the -"xcodebuild" man page for more information. + +This will build the "Release" configuration of gtest.framework in your +default build location. See the "xcodebuild" man page for more information about +building different configurations and building in different locations. To test the gtest.framework in Xcode, change the active target to "Check" and then build. This target builds all of the tests and then runs them. Don't worry @@ -212,21 +219,39 @@ if you see some errors. Xcode reports all test failures (even the intentional ones) as errors. However, you should see a "Build succeeded" message at the end of the build log. To run all of the tests from the command line, enter: - xcodebuid -target Check + xcodebuild -target Check + +Installation with xcodebuild requires specifying an installation desitination +directory, known as the DSTROOT. Three items will be installed when using +xcodebuild: + + $DSTROOT/Library/Frameworks/gtest.framework + $DSTROOT/usr/local/lib/libgtest.a + $DSTROOT/usr/local/lib/libgtest_main.a + +You specify the installation directory on the command line with the other +xcodebuild options. Here's how you would install in a user-visible location: + + xcodebuild install DSTROOT=~ + +To perform a system-wide inistall, escalate to an administrator and specify +the file system root as the DSTROOT: + + sudo xcodebuild install DSTROOT=/ + +To uninstall gtest.framework via the command line, you need to delete the three +items listed above. Remember to escalate to an administrator if deleting these +from the system-wide location using the commands listed below: + + sudo rm -r /Library/Frameworks/gtest.framework + sudo rm /usr/local/lib/libgtest.a + sudo rm /usr/local/lib/libgtest_main.a It is also possible to build and execute individual tests within Xcode. Each test has its own Xcode "Target" and Xcode "Executable". To build any of the tests, change the active target and the active executable to the test of interest and then build and run. -NOTE: Several tests use a Python script to run the test executable. These can be -run from Xcode by creating a "Custom Executable". For example, to run the Python -script which executes the gtest_color_test, select the Project->New Custom -Executable... menu item. When prompted, set the "Executable Name" to something -like "run_gtest_color_test" and set the "Executable Path" to the path of the -gtest_color_test.py script. Finally, choose "Run" from the Run menu and check -the Console for the results. - Individual tests can be built from the command line using: xcodebuild -target <test_name> @@ -235,21 +260,14 @@ These tests can be executed from the command line by moving to the build directory and then (in bash) export DYLD_FRAMEWORK_PATH=`pwd` - ./<test_name> # (if it is not a python test, e.g. ./gtest_unittest) - # OR - ./<test_name>.py # (if it is a python test, e.g. ./gtest_color_test.py) - -To use the gtest.framework for your own tests, first, add the framework to Xcode -project. Next, create a new executable target and add the framework to the -"Link Binary With Libraries" build phase. Select "Edit Active Executable" from -the "Project" menu. In the "Arguments" tab, add - - "DYLD_FRAMEWORK_PATH" : "/real/framework/path" - -in the "Variables to be set in the environment:" list, where you replace -"/real/framework/path" with the actual location of the gtest.framework. Now -when you run your executable, it will load the framework and your test will -run as expected. + ./<test_name> # (e.g. ./gtest_unittest) + +To use gtest.framework for your own tests, first, install the framework using +the steps described above. Then add it to your Xcode project by selecting +Project->Add to Project... from the main menu. Next, add libgtest_main.a from +gtest.framework/Resources directory using the same menu command. Finally, +create a new executable target and add gtest.framework and libgtest_main.a to +the "Link Binary With Libraries" build phase. ### Using GNU Make ### The make/ directory contains a Makefile that you can use to build diff --git a/gtest/configure b/gtest/configure index 876ba74..cb3877f 100755 --- a/gtest/configure +++ b/gtest/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for Google C++ Testing Framework 1.3.0. +# Generated by GNU Autoconf 2.61 for Google C++ Testing Framework 1.4.0. # # Report bugs to <googletestframework@googlegroups.com>. # @@ -723,8 +723,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='Google C++ Testing Framework' PACKAGE_TARNAME='gtest' -PACKAGE_VERSION='1.3.0' -PACKAGE_STRING='Google C++ Testing Framework 1.3.0' +PACKAGE_VERSION='1.4.0' +PACKAGE_STRING='Google C++ Testing Framework 1.4.0' PACKAGE_BUGREPORT='googletestframework@googlegroups.com' ac_unique_file="./COPYING" @@ -1398,7 +1398,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Google C++ Testing Framework 1.3.0 to adapt to many kinds of systems. +\`configure' configures Google C++ Testing Framework 1.4.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1468,7 +1468,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Google C++ Testing Framework 1.3.0:";; + short | recursive ) echo "Configuration of Google C++ Testing Framework 1.4.0:";; esac cat <<\_ACEOF @@ -1567,7 +1567,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Google C++ Testing Framework configure 1.3.0 +Google C++ Testing Framework configure 1.4.0 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1581,7 +1581,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Google C++ Testing Framework $as_me 1.3.0, which was +It was created by Google C++ Testing Framework $as_me 1.4.0, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2285,7 +2285,7 @@ fi # Define the identity of the package. PACKAGE='gtest' - VERSION='1.3.0' + VERSION='1.4.0' cat >>confdefs.h <<_ACEOF @@ -16123,7 +16123,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Google C++ Testing Framework $as_me 1.3.0, which was +This file was extended by Google C++ Testing Framework $as_me 1.4.0, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16176,7 +16176,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -Google C++ Testing Framework config.status 1.3.0 +Google C++ Testing Framework config.status 1.4.0 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/gtest/configure.ac b/gtest/configure.ac index 92670bf..709b024 100644 --- a/gtest/configure.ac +++ b/gtest/configure.ac @@ -5,7 +5,7 @@ m4_include(m4/acx_pthread.m4) # "[1.0.1]"). It also asumes that there won't be any closing parenthesis # between "AC_INIT(" and the closing ")" including comments and strings. AC_INIT([Google C++ Testing Framework], - [1.3.0], + [1.4.0], [googletestframework@googlegroups.com], [gtest]) diff --git a/gtest/include/gtest/gtest-death-test.h b/gtest/include/gtest/gtest-death-test.h index 410654b..fdb497f 100644 --- a/gtest/include/gtest/gtest-death-test.h +++ b/gtest/include/gtest/gtest-death-test.h @@ -181,6 +181,9 @@ class ExitedWithCode { explicit ExitedWithCode(int exit_code); bool operator()(int exit_status) const; private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + const int exit_code_; }; @@ -242,10 +245,10 @@ class KilledBySignal { #ifdef NDEBUG #define EXPECT_DEBUG_DEATH(statement, regex) \ - do { statement; } while (false) + do { statement; } while (::testing::internal::AlwaysFalse()) #define ASSERT_DEBUG_DEATH(statement, regex) \ - do { statement; } while (false) + do { statement; } while (::testing::internal::AlwaysFalse()) #else @@ -260,7 +263,7 @@ class KilledBySignal { // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if -// death tests are supported; otherwise they expand to empty. This is +// death tests are supported; otherwise they just issue a warning. This is // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST @@ -270,13 +273,9 @@ class KilledBySignal { ASSERT_DEATH(statement, regex) #else #define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_LOG_(WARNING, \ - "Death tests are not supported on this platform. The statement" \ - " '" #statement "' can not be verified") + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) #define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_LOG_(WARNING, \ - "Death tests are not supported on this platform. The statement" \ - " '" #statement "' can not be verified") + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) #endif } // namespace testing diff --git a/gtest/include/gtest/gtest-spi.h b/gtest/include/gtest/gtest-spi.h index a4e387a..2953411 100644 --- a/gtest/include/gtest/gtest-spi.h +++ b/gtest/include/gtest/gtest-spi.h @@ -97,12 +97,12 @@ class SingleFailureChecker { public: // The constructor remembers the arguments. SingleFailureChecker(const TestPartResultArray* results, - TestPartResultType type, + TestPartResult::Type type, const char* substr); ~SingleFailureChecker(); private: const TestPartResultArray* const results_; - const TestPartResultType type_; + const TestPartResult::Type type_; const String substr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); @@ -143,14 +143,14 @@ class SingleFailureChecker { };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do { \ @@ -160,14 +160,14 @@ class SingleFailureChecker { };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ALL_THREADS, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to // generate Google Test non-fatal failures. It asserts that the given @@ -190,32 +190,43 @@ class SingleFailureChecker { // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor -// works. The AcceptsMacroThatExpandsToUnprotectedComma test in -// gtest_unittest.cc will fail to compile if we do that. +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. #define EXPECT_NONFATAL_FAILURE(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - statement;\ + if (::testing::internal::AlwaysTrue()) { statement; }\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ >est_failures);\ - statement;\ + if (::testing::internal::AlwaysTrue()) { statement; }\ }\ - } while (false) + } while (::testing::internal::AlwaysFalse()) #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/gtest/include/gtest/gtest-test-part.h b/gtest/include/gtest/gtest-test-part.h index d5b2713..58e7df9 100644 --- a/gtest/include/gtest/gtest-test-part.h +++ b/gtest/include/gtest/gtest-test-part.h @@ -39,24 +39,24 @@ namespace testing { -// The possible outcomes of a test part (i.e. an assertion or an -// explicit SUCCEED(), FAIL(), or ADD_FAILURE()). -enum TestPartResultType { - TPRT_SUCCESS, // Succeeded. - TPRT_NONFATAL_FAILURE, // Failed but the test can continue. - TPRT_FATAL_FAILURE // Failed and the test should be terminated. -}; - // A copyable object representing the result of a test part (i.e. an // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // // Don't inherit from TestPartResult as its destructor is not virtual. class TestPartResult { public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + // C'tor. TestPartResult does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestPartResult object. - TestPartResult(TestPartResultType type, + TestPartResult(Type type, const char* file_name, int line_number, const char* message) @@ -68,7 +68,7 @@ class TestPartResult { } // Gets the outcome of the test part. - TestPartResultType type() const { return type_; } + Type type() const { return type_; } // Gets the name of the source file where the test part took place, or // NULL if it's unknown. @@ -85,18 +85,18 @@ class TestPartResult { const char* message() const { return message_.c_str(); } // Returns true iff the test part passed. - bool passed() const { return type_ == TPRT_SUCCESS; } + bool passed() const { return type_ == kSuccess; } // Returns true iff the test part failed. - bool failed() const { return type_ != TPRT_SUCCESS; } + bool failed() const { return type_ != kSuccess; } // Returns true iff the test part non-fatally failed. - bool nonfatally_failed() const { return type_ == TPRT_NONFATAL_FAILURE; } + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } // Returns true iff the test part fatally failed. - bool fatally_failed() const { return type_ == TPRT_FATAL_FAILURE; } + bool fatally_failed() const { return type_ == kFatalFailure; } private: - TestPartResultType type_; + Type type_; // Gets the summary of the failure message by omitting the stack // trace in it. diff --git a/gtest/include/gtest/gtest.h b/gtest/include/gtest/gtest.h index 90c36a5..9be15fb 100644 --- a/gtest/include/gtest/gtest.h +++ b/gtest/include/gtest/gtest.h @@ -51,9 +51,6 @@ #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_ -// The following platform macro is used throughout Google Test: -// _WIN32_WCE Windows CE (set in project files) - #include <limits> #include <gtest/internal/gtest-internal.h> #include <gtest/internal/gtest-string.h> @@ -130,7 +127,7 @@ GTEST_DECLARE_int32_(repeat); // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); -// When this flag is specified, tests' order is randomized on every run. +// When this flag is specified, tests' order is randomized on every iteration. GTEST_DECLARE_bool_(shuffle); // This flag specifies the maximum number of stack frames to be @@ -150,16 +147,19 @@ namespace internal { class AssertHelper; class DefaultGlobalTestPartResultReporter; class ExecDeathTest; +class NoExecDeathTest; class FinalSuccessChecker; class GTestFlagSaver; -class TestCase; class TestInfoImpl; class TestResultAccessor; -class UnitTestAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; class WindowsDeathTest; class UnitTestImpl* GetUnitTestImpl(); -void ReportFailureInUnknownLocation(TestPartResultType result_type, +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const String& message); +class PrettyUnitTestResultPrinter; +class XmlUnitTestResultPrinter; // Converts a streamable value to a String. A NULL pointer is // converted to "(null)". When the input value is a ::string, @@ -366,8 +366,6 @@ class Test { typedef internal::TimeInMillis TimeInMillis; -namespace internal { - // A copyable object representing a user specified test property which can be // output as a key/value string pair. // @@ -450,14 +448,14 @@ class TestResult { const TestProperty& GetTestProperty(int i) const; private: + friend class TestInfo; + friend class UnitTest; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::ExecDeathTest; friend class internal::TestInfoImpl; friend class internal::TestResultAccessor; friend class internal::UnitTestImpl; friend class internal::WindowsDeathTest; - friend class testing::TestInfo; - friend class testing::UnitTest; // Gets the vector of TestPartResults. const internal::Vector<TestPartResult>& test_part_results() const { @@ -516,8 +514,6 @@ class TestResult { GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); }; // class TestResult -} // namespace internal - // A TestInfo object stores the following information about a test: // // Test case name @@ -566,16 +562,16 @@ class TestInfo { bool should_run() const; // Returns the result of the test. - const internal::TestResult* result() const; + const TestResult* result() const; private: #if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; friend class internal::TestInfoImpl; friend class internal::UnitTestImpl; - friend class Test; - friend class internal::TestCase; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* test_case_comment, const char* comment, @@ -608,8 +604,6 @@ class TestInfo { GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; -namespace internal { - // A test case, which consists of a vector of TestInfos. // // TestCase is not copyable. @@ -670,7 +664,7 @@ class TestCase { const TestInfo* GetTestInfo(int i) const; private: - friend class testing::Test; + friend class Test; friend class internal::UnitTestImpl; // Gets the (mutable) vector of TestInfos in this TestCase. @@ -681,6 +675,10 @@ class TestCase { return *test_info_list_; } + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + // Sets the should_run member. void set_should_run(bool should) { should_run_ = should; } @@ -699,9 +697,6 @@ class TestCase { // Runs every test in this TestCase. void Run(); - // Runs every test in the given TestCase. - static void RunTestCase(TestCase * test_case) { test_case->Run(); } - // Returns true iff test passed. static bool TestPassed(const TestInfo * test_info); @@ -714,12 +709,23 @@ class TestCase { // Returns true if the given test should run. static bool ShouldRunTest(const TestInfo *test_info); + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + // Name of the test case. internal::String name_; // Comment on the test case. internal::String comment_; - // Vector of TestInfos. - internal::Vector<TestInfo*>* test_info_list_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + const internal::scoped_ptr<internal::Vector<TestInfo*> > test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + const internal::scoped_ptr<internal::Vector<int> > test_indices_; // Pointer to the function that sets up the test case. Test::SetUpTestCaseFunc set_up_tc_; // Pointer to the function that tears down the test case. @@ -733,8 +739,6 @@ class TestCase { GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); }; -} // namespace internal - // An Environment object is capable of setting up and tearing down an // environment. The user should subclass this to define his own // environment(s). @@ -766,6 +770,158 @@ class Environment { virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCESS(). + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + // A UnitTest consists of a vector of TestCases. // // This is a singleton class. The only instance of UnitTest is @@ -797,7 +953,7 @@ class UnitTest { // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. - const internal::TestCase* current_test_case() const; + const TestCase* current_test_case() const; // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. @@ -814,36 +970,6 @@ class UnitTest { internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); #endif // GTEST_HAS_PARAM_TEST - private: - // Registers and returns a global test environment. When a test - // program is run, all global test environments will be set-up in - // the order they were registered. After all tests in the program - // have finished, all global test environments will be torn-down in - // the *reverse* order they were registered. - // - // The UnitTest object takes ownership of the given environment. - // - // This method can only be called from the main thread. - Environment* AddEnvironment(Environment* env); - - // Adds a TestPartResult to the current TestResult object. All - // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) - // eventually call this to report their results. The user code - // should use the assertion macros instead of calling this directly. - void AddTestPartResult(TestPartResultType result_type, - const char* file_name, - int line_number, - const internal::String& message, - const internal::String& os_stack_trace); - - // Adds a TestProperty to the current TestResult object. If the result already - // contains a property with the same key, the value will be updated. - void RecordPropertyForCurrentTest(const char* key, const char* value); - - // Accessors for the implementation object. - internal::UnitTestImpl* impl() { return impl_; } - const internal::UnitTestImpl* impl() const { return impl_; } - // Gets the number of successful test cases. int successful_test_case_count() const; @@ -884,29 +1010,56 @@ class UnitTest { // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. - const internal::TestCase* GetTestCase(int i) const; + const TestCase* GetTestCase(int i) const; - // ScopedTrace is a friend as it needs to modify the per-thread - // trace stack, which is a private member of UnitTest. - // TODO(vladl@google.com): Order all declarations according to the style - // guide after publishing of the above methods is done. + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; friend class internal::ScopedTrace; friend Environment* AddGlobalTestEnvironment(Environment* env); friend internal::UnitTestImpl* internal::GetUnitTestImpl(); - friend class internal::AssertHelper; - friend class Test; friend void internal::ReportFailureInUnknownLocation( - TestPartResultType result_type, + TestPartResult::Type result_type, const internal::String& message); - // TODO(vladl@google.com): Remove these when publishing the new accessors. - friend class PrettyUnitTestResultPrinter; - friend class XmlUnitTestResultPrinter; - friend class internal::UnitTestAccessor; - friend class FinalSuccessChecker; - FRIEND_TEST(ApiTest, UnitTestImmutableAccessorsWork); - FRIEND_TEST(ApiTest, TestCaseImmutableAccessorsWork); - FRIEND_TEST(ApiTest, DisabledTestCaseAccessorsWork); - // Creates an empty UnitTest. UnitTest(); @@ -1297,16 +1450,38 @@ AssertionResult DoubleNearPredFormat(const char* expr1, class AssertHelper { public: // Constructor. - AssertHelper(TestPartResultType type, const char* file, int line, + AssertHelper(TestPartResult::Type type, + const char* file, + int line, const char* message); + ~AssertHelper(); + // Message assignment is a semantic trick to enable assertion // streaming; see the GTEST_MESSAGE_ macro below. void operator=(const Message& message) const; + private: - TestPartResultType const type_; - const char* const file_; - int const line_; - String const message_; + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + String const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; diff --git a/gtest/include/gtest/internal/gtest-death-test-internal.h b/gtest/include/gtest/internal/gtest-death-test-internal.h index 143e58a..5aba1a0 100644 --- a/gtest/include/gtest/internal/gtest-death-test-internal.h +++ b/gtest/include/gtest/internal/gtest-death-test-internal.h @@ -153,7 +153,7 @@ bool ExitedUnsuccessfully(int exit_status); // ASSERT_EXIT*, and EXPECT_EXIT*. #define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (true) { \ + if (::testing::internal::AlwaysTrue()) { \ const ::testing::internal::RE& gtest_regex = (regex); \ ::testing::internal::DeathTest* gtest_dt; \ if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ @@ -172,7 +172,7 @@ bool ExitedUnsuccessfully(int exit_status); case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ - GTEST_HIDE_UNREACHABLE_CODE_(statement); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ @@ -219,6 +219,53 @@ class InternalRunDeathTestFlag { // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + #endif // GTEST_HAS_DEATH_TEST } // namespace internal diff --git a/gtest/include/gtest/internal/gtest-internal.h b/gtest/include/gtest/internal/gtest-internal.h index be37726..7033b0c 100644 --- a/gtest/include/gtest/internal/gtest-internal.h +++ b/gtest/include/gtest/internal/gtest-internal.h @@ -107,7 +107,6 @@ class Test; // Represents a test. class TestInfo; // Information about a test. class TestPartResult; // Result of a test part. class UnitTest; // A collection of test cases. -class UnitTestEventListenerInterface; // Listens to Google Test events. namespace internal { @@ -726,8 +725,8 @@ class TypeParameterizedTestCase { template <GTEST_TEMPLATE_ Fixture, typename Types> class TypeParameterizedTestCase<Fixture, Templates0, Types> { public: - static bool Register(const char* prefix, const char* case_name, - const char* test_names) { + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { return true; } }; @@ -746,9 +745,37 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> { // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count); -// A helper for suppressing warnings on unreachable code in some macros. +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. bool AlwaysTrue(); +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + } // namespace internal } // namespace testing @@ -757,18 +784,18 @@ bool AlwaysTrue(); = ::testing::Message() #define GTEST_FATAL_FAILURE_(message) \ - return GTEST_MESSAGE_(message, ::testing::TPRT_FATAL_FAILURE) + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) #define GTEST_NONFATAL_FAILURE_(message) \ - GTEST_MESSAGE_(message, ::testing::TPRT_NONFATAL_FAILURE) + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) #define GTEST_SUCCESS_(message) \ - GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS) + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) // Suppresses MSVC warnings 4072 (unreachable code) for the code following // statement if it returns or throws (or doesn't return or throw in some // situations). -#define GTEST_HIDE_UNREACHABLE_CODE_(statement) \ +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ if (::testing::internal::AlwaysTrue()) { statement; } #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ @@ -776,7 +803,7 @@ bool AlwaysTrue(); if (const char* gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ - GTEST_HIDE_UNREACHABLE_CODE_(statement); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ @@ -800,7 +827,7 @@ bool AlwaysTrue(); GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ try { \ - GTEST_HIDE_UNREACHABLE_CODE_(statement); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ @@ -816,7 +843,7 @@ bool AlwaysTrue(); if (const char* gtest_msg = "") { \ bool gtest_caught_any = false; \ try { \ - GTEST_HIDE_UNREACHABLE_CODE_(statement); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ @@ -833,7 +860,7 @@ bool AlwaysTrue(); #define GTEST_TEST_BOOLEAN_(boolexpr, booltext, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (boolexpr) \ + if (::testing::internal::IsTrue(boolexpr)) \ ; \ else \ fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected) @@ -842,7 +869,7 @@ bool AlwaysTrue(); GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - GTEST_HIDE_UNREACHABLE_CODE_(statement); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ diff --git a/gtest/include/gtest/internal/gtest-param-util-generated.h b/gtest/include/gtest/internal/gtest-param-util-generated.h index ad06e02..1358c32 100644 --- a/gtest/include/gtest/internal/gtest-param-util-generated.h +++ b/gtest/include/gtest/internal/gtest-param-util-generated.h @@ -63,6 +63,9 @@ class ValueArray1 { operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + const T1 v1_; }; @@ -78,6 +81,9 @@ class ValueArray2 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + const T1 v1_; const T2 v2_; }; @@ -94,6 +100,9 @@ class ValueArray3 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -112,6 +121,9 @@ class ValueArray4 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -131,6 +143,9 @@ class ValueArray5 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -152,6 +167,9 @@ class ValueArray6 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -174,6 +192,9 @@ class ValueArray7 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -198,6 +219,9 @@ class ValueArray8 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -223,6 +247,9 @@ class ValueArray9 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -249,6 +276,9 @@ class ValueArray10 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -277,6 +307,9 @@ class ValueArray11 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -307,6 +340,9 @@ class ValueArray12 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -339,6 +375,9 @@ class ValueArray13 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -372,6 +411,9 @@ class ValueArray14 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -406,6 +448,9 @@ class ValueArray15 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -443,6 +488,9 @@ class ValueArray16 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -481,6 +529,9 @@ class ValueArray17 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -520,6 +571,9 @@ class ValueArray18 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -560,6 +614,9 @@ class ValueArray19 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -602,6 +659,9 @@ class ValueArray20 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -646,6 +706,9 @@ class ValueArray21 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -691,6 +754,9 @@ class ValueArray22 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -739,6 +805,9 @@ class ValueArray23 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -788,6 +857,9 @@ class ValueArray24 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -838,6 +910,9 @@ class ValueArray25 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -890,6 +965,9 @@ class ValueArray26 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -944,6 +1022,9 @@ class ValueArray27 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -999,6 +1080,9 @@ class ValueArray28 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1055,6 +1139,9 @@ class ValueArray29 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1113,6 +1200,9 @@ class ValueArray30 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1173,6 +1263,9 @@ class ValueArray31 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1234,6 +1327,9 @@ class ValueArray32 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1297,6 +1393,9 @@ class ValueArray33 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1361,6 +1460,9 @@ class ValueArray34 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1427,6 +1529,9 @@ class ValueArray35 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1495,6 +1600,9 @@ class ValueArray36 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1565,6 +1673,9 @@ class ValueArray37 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1636,6 +1747,9 @@ class ValueArray38 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1708,6 +1822,9 @@ class ValueArray39 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1782,6 +1899,9 @@ class ValueArray40 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1858,6 +1978,9 @@ class ValueArray41 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -1935,6 +2058,9 @@ class ValueArray42 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2013,6 +2139,9 @@ class ValueArray43 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2093,6 +2222,9 @@ class ValueArray44 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2174,6 +2306,9 @@ class ValueArray45 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2257,6 +2392,9 @@ class ValueArray46 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2343,6 +2481,9 @@ class ValueArray47 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2430,6 +2571,9 @@ class ValueArray48 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2518,6 +2662,9 @@ class ValueArray49 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2607,6 +2754,9 @@ class ValueArray50 { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + const T1 v1_; const T2 v2_; const T3 v3_; @@ -2757,6 +2907,9 @@ class CartesianProductGenerator2 current2_ == end2_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -2767,11 +2920,14 @@ class CartesianProductGenerator2 const typename ParamGenerator<T2>::iterator end2_; typename ParamGenerator<T2>::iterator current2_; ParamType current_value_; - }; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; -}; +}; // class CartesianProductGenerator2 template <typename T1, typename T2, typename T3> @@ -2879,6 +3035,9 @@ class CartesianProductGenerator3 current3_ == end3_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -2892,12 +3051,15 @@ class CartesianProductGenerator3 const typename ParamGenerator<T3>::iterator end3_; typename ParamGenerator<T3>::iterator current3_; ParamType current_value_; - }; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; const ParamGenerator<T3> g3_; -}; +}; // class CartesianProductGenerator3 template <typename T1, typename T2, typename T3, typename T4> @@ -3020,6 +3182,9 @@ class CartesianProductGenerator4 current4_ == end4_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3036,13 +3201,16 @@ class CartesianProductGenerator4 const typename ParamGenerator<T4>::iterator end4_; typename ParamGenerator<T4>::iterator current4_; ParamType current_value_; - }; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; const ParamGenerator<T3> g3_; const ParamGenerator<T4> g4_; -}; +}; // class CartesianProductGenerator4 template <typename T1, typename T2, typename T3, typename T4, typename T5> @@ -3177,6 +3345,9 @@ class CartesianProductGenerator5 current5_ == end5_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3196,14 +3367,17 @@ class CartesianProductGenerator5 const typename ParamGenerator<T5>::iterator end5_; typename ParamGenerator<T5>::iterator current5_; ParamType current_value_; - }; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; const ParamGenerator<T3> g3_; const ParamGenerator<T4> g4_; const ParamGenerator<T5> g5_; -}; +}; // class CartesianProductGenerator5 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3353,6 +3527,9 @@ class CartesianProductGenerator6 current6_ == end6_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3375,7 +3552,10 @@ class CartesianProductGenerator6 const typename ParamGenerator<T6>::iterator end6_; typename ParamGenerator<T6>::iterator current6_; ParamType current_value_; - }; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -3383,7 +3563,7 @@ class CartesianProductGenerator6 const ParamGenerator<T4> g4_; const ParamGenerator<T5> g5_; const ParamGenerator<T6> g6_; -}; +}; // class CartesianProductGenerator6 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3546,6 +3726,9 @@ class CartesianProductGenerator7 current7_ == end7_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3571,7 +3754,10 @@ class CartesianProductGenerator7 const typename ParamGenerator<T7>::iterator end7_; typename ParamGenerator<T7>::iterator current7_; ParamType current_value_; - }; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -3580,7 +3766,7 @@ class CartesianProductGenerator7 const ParamGenerator<T5> g5_; const ParamGenerator<T6> g6_; const ParamGenerator<T7> g7_; -}; +}; // class CartesianProductGenerator7 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3758,6 +3944,9 @@ class CartesianProductGenerator8 current8_ == end8_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -3786,7 +3975,10 @@ class CartesianProductGenerator8 const typename ParamGenerator<T8>::iterator end8_; typename ParamGenerator<T8>::iterator current8_; ParamType current_value_; - }; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -3796,7 +3988,7 @@ class CartesianProductGenerator8 const ParamGenerator<T6> g6_; const ParamGenerator<T7> g7_; const ParamGenerator<T8> g8_; -}; +}; // class CartesianProductGenerator8 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -3987,6 +4179,9 @@ class CartesianProductGenerator9 current9_ == end9_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -4018,7 +4213,10 @@ class CartesianProductGenerator9 const typename ParamGenerator<T9>::iterator end9_; typename ParamGenerator<T9>::iterator current9_; ParamType current_value_; - }; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -4029,7 +4227,7 @@ class CartesianProductGenerator9 const ParamGenerator<T7> g7_; const ParamGenerator<T8> g8_; const ParamGenerator<T9> g9_; -}; +}; // class CartesianProductGenerator9 template <typename T1, typename T2, typename T3, typename T4, typename T5, @@ -4233,6 +4431,9 @@ class CartesianProductGenerator10 current10_ == end10_; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -4267,7 +4468,10 @@ class CartesianProductGenerator10 const typename ParamGenerator<T10>::iterator end10_; typename ParamGenerator<T10>::iterator current10_; ParamType current_value_; - }; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); const ParamGenerator<T1> g1_; const ParamGenerator<T2> g2_; @@ -4279,7 +4483,7 @@ class CartesianProductGenerator10 const ParamGenerator<T8> g8_; const ParamGenerator<T9> g9_; const ParamGenerator<T10> g10_; -}; +}; // class CartesianProductGenerator10 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -4302,9 +4506,12 @@ CartesianProductHolder2(const Generator1& g1, const Generator2& g2) } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + const Generator1 g1_; const Generator2 g2_; -}; +}; // class CartesianProductHolder2 template <class Generator1, class Generator2, class Generator3> class CartesianProductHolder3 { @@ -4322,10 +4529,13 @@ CartesianProductHolder3(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; -}; +}; // class CartesianProductHolder3 template <class Generator1, class Generator2, class Generator3, class Generator4> @@ -4345,11 +4555,14 @@ CartesianProductHolder4(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; -}; +}; // class CartesianProductHolder4 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5> @@ -4370,12 +4583,15 @@ CartesianProductHolder5(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; -}; +}; // class CartesianProductHolder5 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6> @@ -4399,13 +4615,16 @@ CartesianProductHolder6(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; -}; +}; // class CartesianProductHolder6 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7> @@ -4431,6 +4650,9 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4438,7 +4660,7 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2, const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; -}; +}; // class CartesianProductHolder7 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7, @@ -4467,6 +4689,9 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4475,7 +4700,7 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2, const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; -}; +}; // class CartesianProductHolder8 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7, @@ -4507,6 +4732,9 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4516,7 +4744,7 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2, const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; -}; +}; // class CartesianProductHolder9 template <class Generator1, class Generator2, class Generator3, class Generator4, class Generator5, class Generator6, class Generator7, @@ -4550,6 +4778,9 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2, } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; @@ -4560,7 +4791,7 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2, const Generator8 g8_; const Generator9 g9_; const Generator10 g10_; -}; +}; // class CartesianProductHolder10 #endif // GTEST_HAS_COMBINE diff --git a/gtest/include/gtest/internal/gtest-param-util-generated.h.pump b/gtest/include/gtest/internal/gtest-param-util-generated.h.pump index 54b2dc1..2da2872 100644 --- a/gtest/include/gtest/internal/gtest-param-util-generated.h.pump +++ b/gtest/include/gtest/internal/gtest-param-util-generated.h.pump @@ -64,6 +64,9 @@ class ValueArray1 { operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + const T1 v1_; }; @@ -83,6 +86,9 @@ class ValueArray$i { } private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray$i& other); + $for j [[ const T$j v$(j)_; @@ -201,6 +207,9 @@ $for j || [[ ]]; } + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<ParamType>* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. @@ -212,14 +221,17 @@ $for j [[ ]] ParamType current_value_; - }; + }; // class CartesianProductGenerator$i::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator$i& other); $for j [[ const ParamGenerator<T$j> g$(j)_; ]] -}; +}; // class CartesianProductGenerator$i ]] @@ -250,12 +262,15 @@ $for j,[[ } private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder$i& other); + $for j [[ const Generator$j g$(j)_; ]] -}; +}; // class CartesianProductHolder$i ]] diff --git a/gtest/include/gtest/internal/gtest-param-util.h b/gtest/include/gtest/internal/gtest-param-util.h index 34361ab..dcc5494 100644 --- a/gtest/include/gtest/internal/gtest-param-util.h +++ b/gtest/include/gtest/internal/gtest-param-util.h @@ -248,6 +248,9 @@ class RangeGenerator : public ParamGeneratorInterface<T> { : base_(other.base_), value_(other.value_), index_(other.index_), step_(other.step_) {} + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + const ParamGeneratorInterface<T>* const base_; T value_; int index_; @@ -263,6 +266,9 @@ class RangeGenerator : public ParamGeneratorInterface<T> { return end_index; } + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + const T begin_; const T end_; const IncrementT step_; @@ -349,7 +355,10 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { // Use of scoped_ptr helps manage cached value's lifetime, // which is bound by the lifespan of the iterator itself. mutable scoped_ptr<const T> value_; - }; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); const ContainerType container_; }; // class ValuesInIteratorRangeGenerator diff --git a/gtest/include/gtest/internal/gtest-port.h b/gtest/include/gtest/internal/gtest-port.h index a5adbc0..ee97881 100644 --- a/gtest/include/gtest/internal/gtest-port.h +++ b/gtest/include/gtest/internal/gtest-port.h @@ -77,7 +77,10 @@ // GTEST_OS_MAC - Mac OS X // GTEST_OS_SOLARIS - Sun Solaris // GTEST_OS_SYMBIAN - Symbian -// GTEST_OS_WINDOWS - Windows +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINODWS_MOBILE - Windows Mobile // GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the @@ -184,6 +187,13 @@ #define GTEST_OS_SYMBIAN 1 #elif defined _WIN32 #define GTEST_OS_WINDOWS 1 +#ifdef _WIN32_WCE +#define GTEST_OS_WINDOWS_MOBILE 1 +#elif defined(__MINGW__) || defined(__MINGW32__) +#define GTEST_OS_WINDOWS_MINGW 1 +#else +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif // _WIN32_WCE #elif defined __APPLE__ #define GTEST_OS_MAC 1 #elif defined __linux__ @@ -210,10 +220,10 @@ #elif GTEST_OS_WINDOWS -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE #include <direct.h> // NOLINT #include <io.h> // NOLINT -#endif // !_WIN32_WCE +#endif // <regex.h> is not available on Windows. Use our own simple regex // implementation instead. @@ -449,11 +459,9 @@ // (this is covered by GTEST_HAS_STD_STRING guard). // 3. abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. -#if GTEST_HAS_STD_STRING && (GTEST_OS_LINUX || \ - GTEST_OS_MAC || \ - GTEST_OS_CYGWIN || \ - (GTEST_OS_WINDOWS && (_MSC_VER >= 1400) && \ - !defined(_WIN32_WCE))) +#if GTEST_HAS_STD_STRING && \ + (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || GTEST_OS_WINDOWS_MINGW) #define GTEST_HAS_DEATH_TEST 1 #include <vector> // NOLINT #endif @@ -569,6 +577,10 @@ typedef ::std::stringstream StrStream; typedef ::std::strstream StrStream; #endif // GTEST_HAS_STD_STRING +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +bool IsTrue(bool condition); + // Defines scoped_ptr. // This implementation of scoped_ptr is PARTIAL - it only contains @@ -591,7 +603,7 @@ class scoped_ptr { void reset(T* p = NULL) { if (p != ptr_) { - if (sizeof(T) > 0) { // Makes sure T is a complete type. + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. delete ptr_; } ptr_ = p; @@ -672,7 +684,8 @@ class RE { }; // Defines logging utilities: -// GTEST_LOG_() - logs messages at the specified severity level. +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. @@ -683,13 +696,27 @@ enum GTestLogSeverity { GTEST_FATAL }; -void GTestLog(GTestLogSeverity severity, const char* file, - int line, const char* msg); +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); -#define GTEST_LOG_(severity, msg)\ - ::testing::internal::GTestLog(\ - ::testing::internal::GTEST_##severity, __FILE__, __LINE__, \ - (::testing::Message() << (msg)).GetString().c_str()) + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } @@ -820,29 +847,29 @@ inline int StrCaseCmp(const char* s1, const char* s2) { } inline char* StrDup(const char* src) { return strdup(src); } #else // !__BORLANDC__ -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE inline int IsATTY(int /* fd */) { return 0; } -#else // !_WIN32_WCE +#else inline int IsATTY(int fd) { return _isatty(fd); } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } #endif // __BORLANDC__ -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. -#else // !_WIN32_WCE +#else inline int FileNo(FILE* file) { return _fileno(file); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE #else @@ -876,20 +903,20 @@ inline const char* StrNCpy(char* dest, const char* src, size_t n) { // StrError() aren't needed on Windows CE at this time and thus not // defined there. -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { return fopen(path, mode); } -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } #endif inline int FClose(FILE* fp) { return fclose(fp); } -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE inline int Read(int fd, void* buf, unsigned int count) { return static_cast<int>(read(fd, buf, count)); } @@ -900,7 +927,8 @@ inline int Close(int fd) { return close(fd); } inline const char* StrError(int errnum) { return strerror(errnum); } #endif inline const char* GetEnv(const char* name) { -#ifdef _WIN32_WCE // We are on Windows CE, which has no environment variables. +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. return NULL; #elif defined(__BORLANDC__) // Environment variables which we programmatically clear will be set to the @@ -916,14 +944,14 @@ inline const char* GetEnv(const char* name) { #pragma warning(pop) // Restores the warning state. #endif -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE has no C library. The abort() function is used in // several places in Google Test. This implementation provides a reasonable // imitation of standard behaviour. void Abort(); #else inline void Abort() { abort(); } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE } // namespace posix @@ -1011,38 +1039,12 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // condition itself, plus additional message streamed into it, if any, // and then it aborts the program. It aborts the program irrespective of // whether it is built in the debug mode or not. -class GTestCheckProvider { - public: - GTestCheckProvider(const char* condition, const char* file, int line) { - FormatFileLocation(file, line); - ::std::cerr << " ERROR: Condition " << condition << " failed. "; - } - ~GTestCheckProvider() { - ::std::cerr << ::std::endl; - posix::Abort(); - } - void FormatFileLocation(const char* file, int line) { - if (file == NULL) - file = "unknown file"; - if (line < 0) { - ::std::cerr << file << ":"; - } else { -#if _MSC_VER - ::std::cerr << file << "(" << line << "):"; -#else - ::std::cerr << file << ":" << line << ":"; -#endif - } - } - ::std::ostream& GetStream() { return ::std::cerr; } -}; #define GTEST_CHECK_(condition) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (condition) \ + if (::testing::internal::IsTrue(condition)) \ ; \ else \ - ::testing::internal::GTestCheckProvider(\ - #condition, __FILE__, __LINE__).GetStream() + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " // Macro for referencing flags. #define GTEST_FLAG(name) FLAGS_gtest_##name diff --git a/gtest/include/gtest/internal/gtest-string.h b/gtest/include/gtest/internal/gtest-string.h index 566a6b5..4bc8241 100644 --- a/gtest/include/gtest/internal/gtest-string.h +++ b/gtest/include/gtest/internal/gtest-string.h @@ -80,19 +80,6 @@ class String { public: // Static utility methods - // Returns the input if it's not NULL, otherwise returns "(null)". - // This function serves two purposes: - // - // 1. ShowCString(NULL) has type 'const char *', instead of the - // type of NULL (which is int). - // - // 2. In MSVC, streaming a null char pointer to StrStream generates - // an access violation, so we need to convert NULL to "(null)" - // before streaming it. - static inline const char* ShowCString(const char* c_str) { - return c_str ? c_str : "(null)"; - } - // Returns the input enclosed in double quotes if it's not NULL; // otherwise returns "(null)". For example, "\"Hello\"" is returned // for input "Hello". @@ -111,7 +98,7 @@ class String { // memory using malloc(). static const char* CloneCString(const char* c_str); -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be // able to pass strings to Win32 APIs on CE we need to convert them // to 'Unicode', UTF-16. @@ -200,22 +187,29 @@ class String { // C'tors // The default c'tor constructs a NULL string. - String() : c_str_(NULL) {} + String() : c_str_(NULL), length_(0) {} // Constructs a String by cloning a 0-terminated C string. - String(const char* c_str) : c_str_(NULL) { // NOLINT - *this = c_str; + String(const char* c_str) { // NOLINT + if (c_str == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(c_str, strlen(c_str)); + } } // Constructs a String by copying a given number of chars from a - // buffer. E.g. String("hello", 3) will create the string "hel". - String(const char* buffer, size_t len); + // buffer. E.g. String("hello", 3) creates the string "hel", + // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "", + // and String(NULL, 1) results in access violation. + String(const char* buffer, size_t length) { + ConstructNonNull(buffer, length); + } // The copy c'tor creates a new copy of the string. The two // String objects do not share content. - String(const String& str) : c_str_(NULL) { - *this = str; - } + String(const String& str) : c_str_(NULL), length_(0) { *this = str; } // D'tor. String is intended to be a final class, so the d'tor // doesn't need to be virtual. @@ -228,21 +222,23 @@ class String { // character to a String will result in the prefix up to the first // NUL character. #if GTEST_HAS_STD_STRING - String(const ::std::string& str) : c_str_(NULL) { *this = str.c_str(); } + String(const ::std::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } - operator ::std::string() const { return ::std::string(c_str_); } + operator ::std::string() const { return ::std::string(c_str(), length()); } #endif // GTEST_HAS_STD_STRING #if GTEST_HAS_GLOBAL_STRING - String(const ::string& str) : c_str_(NULL) { *this = str.c_str(); } + String(const ::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } - operator ::string() const { return ::string(c_str_); } + operator ::string() const { return ::string(c_str(), length()); } #endif // GTEST_HAS_GLOBAL_STRING // Returns true iff this is an empty string (i.e. ""). - bool empty() const { - return (c_str_ != NULL) && (*c_str_ == '\0'); - } + bool empty() const { return (c_str() != NULL) && (length() == 0); } // Compares this with another String. // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 @@ -251,19 +247,15 @@ class String { // Returns true iff this String equals the given C string. A NULL // string and a non-NULL string are considered not equal. - bool operator==(const char* c_str) const { - return CStringEquals(c_str_, c_str); - } + bool operator==(const char* c_str) const { return Compare(c_str) == 0; } - // Returns true iff this String is less than the given C string. A NULL - // string is considered less than "". + // Returns true iff this String is less than the given String. A + // NULL string is considered less than "". bool operator<(const String& rhs) const { return Compare(rhs) < 0; } // Returns true iff this String doesn't equal the given C string. A NULL // string and a non-NULL string are considered not equal. - bool operator!=(const char* c_str) const { - return !CStringEquals(c_str_, c_str); - } + bool operator!=(const char* c_str) const { return !(*this == c_str); } // Returns true iff this String ends with the given suffix. *Any* // String is considered to end with a NULL or empty suffix. @@ -273,45 +265,66 @@ class String { // case. Any String is considered to end with a NULL or empty suffix. bool EndsWithCaseInsensitive(const char* suffix) const; - // Returns the length of the encapsulated string, or -1 if the + // Returns the length of the encapsulated string, or 0 if the // string is NULL. - int GetLength() const { - return c_str_ ? static_cast<int>(strlen(c_str_)) : -1; - } + size_t length() const { return length_; } // Gets the 0-terminated C string this String object represents. // The String object still owns the string. Therefore the caller // should NOT delete the return value. const char* c_str() const { return c_str_; } - // Sets the 0-terminated C string this String object represents. - // The old string in this object is deleted, and this object will - // own a clone of the input string. This function copies only up to - // length bytes (plus a terminating null byte), or until the first - // null byte, whichever comes first. - // - // This function works even when the c_str parameter has the same - // value as that of the c_str_ field. - void Set(const char* c_str, size_t length); - // Assigns a C string to this object. Self-assignment works. - const String& operator=(const char* c_str); + const String& operator=(const char* c_str) { return *this = String(c_str); } // Assigns a String object to this object. Self-assignment works. - const String& operator=(const String &rhs) { - *this = rhs.c_str_; + const String& operator=(const String& rhs) { + if (this != &rhs) { + delete[] c_str_; + if (rhs.c_str() == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(rhs.c_str(), rhs.length()); + } + } + return *this; } private: - const char* c_str_; -}; + // Constructs a non-NULL String from the given content. This + // function can only be called when data_ has not been allocated. + // ConstructNonNull(NULL, 0) results in an empty string (""). + // ConstructNonNull(NULL, non_zero) is undefined behavior. + void ConstructNonNull(const char* buffer, size_t length) { + char* const str = new char[length + 1]; + memcpy(str, buffer, length); + str[length] = '\0'; + c_str_ = str; + length_ = length; + } -// Streams a String to an ostream. -inline ::std::ostream& operator <<(::std::ostream& os, const String& str) { - // We call String::ShowCString() to convert NULL to "(null)". - // Otherwise we'll get an access violation on Windows. - return os << String::ShowCString(str.c_str()); + const char* c_str_; + size_t length_; +}; // class String + +// Streams a String to an ostream. Each '\0' character in the String +// is replaced with "\\0". +inline ::std::ostream& operator<<(::std::ostream& os, const String& str) { + if (str.c_str() == NULL) { + os << "(null)"; + } else { + const char* const c_str = str.c_str(); + for (size_t i = 0; i != str.length(); i++) { + if (c_str[i] == '\0') { + os << "\\0"; + } else { + os << c_str[i]; + } + } + } + return os; } // Gets the content of the StrStream's buffer as a String. Each '\0' diff --git a/gtest/msvc/gtest-md.sln b/gtest/msvc/gtest-md.sln new file mode 100644 index 0000000..f7908da --- /dev/null +++ b/gtest/msvc/gtest-md.sln @@ -0,0 +1,45 @@ +Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg = Debug|Win32
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0 = Debug|Win32
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg = Release|Win32
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.Build.0 = Release|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.ActiveCfg = Debug|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.Build.0 = Debug|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.ActiveCfg = Release|Win32
+ {3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.Build.0 = Release|Win32
+ {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.ActiveCfg = Debug|Win32
+ {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.Build.0 = Debug|Win32
+ {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.ActiveCfg = Release|Win32
+ {24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.Build.0 = Release|Win32
+ {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.ActiveCfg = Debug|Win32
+ {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.Build.0 = Debug|Win32
+ {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg = Release|Win32
+ {4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/gtest/msvc/gtest-md.vcproj b/gtest/msvc/gtest-md.vcproj new file mode 100644 index 0000000..c78a4a4 --- /dev/null +++ b/gtest/msvc/gtest-md.vcproj @@ -0,0 +1,237 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="gtest-md"
+ ProjectGUID="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ ReferencesPath="">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/gtestd.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ ReferencesPath=""..\include";".."">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/gtest.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\src\gtest-death-test.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\gtest-filepath.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\gtest-port.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\gtest-test-part.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\gtest-typed-test.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\gtest.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\include\gtest\internal\gtest-death-test-internal.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest-death-test.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-filepath.h">
+ </File>
+ <File
+ RelativePath="..\src\gtest-internal-inl.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-internal.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest-message.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-port.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest-spi.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-string.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest_pred_impl.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest_prod.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/gtest/msvc/gtest.sln b/gtest/msvc/gtest.sln index 5619c12..ef4b057 100644 --- a/gtest/msvc/gtest.sln +++ b/gtest/msvc/gtest.sln @@ -11,30 +11,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_uni ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_environment_test", "gtest_environment_test.vcproj", "{DF5FA93D-DC03-41A6-A18C-079198633450}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_color_test_", "gtest_color_test_.vcproj", "{ABC5A7E8-072C-4A2D-B186-19EA5394B9C6}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_env_var_test_", "gtest_env_var_test_.vcproj", "{569C6F70-F41C-47F3-A622-8A88DC43D452}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_output_test_", "gtest_output_test_.vcproj", "{A4903F73-ED6C-4972-863E-F7355EB0145E}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_uninitialized_test_", "gtest_uninitialized_test_.vcproj", "{42B8A077-E162-4540-A688-246296ACAC1D}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -53,30 +33,10 @@ Global {4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0 = Debug|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg = Release|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0 = Release|Win32
- {DF5FA93D-DC03-41A6-A18C-079198633450}.Debug.ActiveCfg = Debug|Win32
- {DF5FA93D-DC03-41A6-A18C-079198633450}.Debug.Build.0 = Debug|Win32
- {DF5FA93D-DC03-41A6-A18C-079198633450}.Release.ActiveCfg = Release|Win32
- {DF5FA93D-DC03-41A6-A18C-079198633450}.Release.Build.0 = Release|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg = Debug|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0 = Debug|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg = Release|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0 = Release|Win32
- {ABC5A7E8-072C-4A2D-B186-19EA5394B9C6}.Debug.ActiveCfg = Debug|Win32
- {ABC5A7E8-072C-4A2D-B186-19EA5394B9C6}.Debug.Build.0 = Debug|Win32
- {ABC5A7E8-072C-4A2D-B186-19EA5394B9C6}.Release.ActiveCfg = Release|Win32
- {ABC5A7E8-072C-4A2D-B186-19EA5394B9C6}.Release.Build.0 = Release|Win32
- {569C6F70-F41C-47F3-A622-8A88DC43D452}.Debug.ActiveCfg = Debug|Win32
- {569C6F70-F41C-47F3-A622-8A88DC43D452}.Debug.Build.0 = Debug|Win32
- {569C6F70-F41C-47F3-A622-8A88DC43D452}.Release.ActiveCfg = Release|Win32
- {569C6F70-F41C-47F3-A622-8A88DC43D452}.Release.Build.0 = Release|Win32
- {A4903F73-ED6C-4972-863E-F7355EB0145E}.Debug.ActiveCfg = Debug|Win32
- {A4903F73-ED6C-4972-863E-F7355EB0145E}.Debug.Build.0 = Debug|Win32
- {A4903F73-ED6C-4972-863E-F7355EB0145E}.Release.ActiveCfg = Release|Win32
- {A4903F73-ED6C-4972-863E-F7355EB0145E}.Release.Build.0 = Release|Win32
- {42B8A077-E162-4540-A688-246296ACAC1D}.Debug.ActiveCfg = Debug|Win32
- {42B8A077-E162-4540-A688-246296ACAC1D}.Debug.Build.0 = Debug|Win32
- {42B8A077-E162-4540-A688-246296ACAC1D}.Release.ActiveCfg = Release|Win32
- {42B8A077-E162-4540-A688-246296ACAC1D}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
diff --git a/gtest/msvc/gtest.vcproj b/gtest/msvc/gtest.vcproj index d38ea3b..09d5b93 100644 --- a/gtest/msvc/gtest.vcproj +++ b/gtest/msvc/gtest.vcproj @@ -12,8 +12,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="">
@@ -26,7 +26,7 @@ RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
@@ -54,8 +54,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath=""..\include";".."">
@@ -65,7 +65,7 @@ RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
diff --git a/gtest/msvc/gtest_environment_test.vcproj b/gtest/msvc/gtest_environment_test.vcproj deleted file mode 100644 index 69d0f42..0000000 --- a/gtest/msvc/gtest_environment_test.vcproj +++ /dev/null @@ -1,144 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="gtest_environment_test"
- ProjectGUID="{DF5FA93D-DC03-41A6-A18C-079198633450}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="3"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_environment_test.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/gtest_unittest.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- RuntimeLibrary="2"
- UsePrecompiledHeader="3"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_environment_test.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- <ProjectReference
- ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
- Name="gtest"/>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
- <File
- RelativePath="..\test\gtest_environment_test.cc">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""..";"..\include""
- UsePrecompiledHeader="0"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""..";"..\include""
- UsePrecompiledHeader="0"/>
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/gtest/msvc/gtest_env_var_test_.vcproj b/gtest/msvc/gtest_main-md.vcproj index a61e7a2..321667f 100644 --- a/gtest/msvc/gtest_env_var_test_.vcproj +++ b/gtest/msvc/gtest_main-md.vcproj @@ -2,8 +2,8 @@ <VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
- Name="gtest_env_var_test_"
- ProjectGUID="{569C6F70-F41C-47F3-A622-8A88DC43D452}"
+ Name="gtest_main-md"
+ ProjectGUID="{3AF54C8A-10BF-4332-9147-F68ED9862033}"
Keyword="Win32Proj">
<Platforms>
<Platform
@@ -12,31 +12,27 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ ReferencesPath="">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
- UsePrecompiledHeader="3"
+ UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_env_var_test_.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/gtest_env_var_test_.pdb"
- SubSystem="1"
- TargetMachine="1"/>
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/$(ProjectName)d.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -52,37 +48,30 @@ <Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
- Name="VCWebDeploymentTool"/>
- <Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ ReferencesPath=""..\include";".."">
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
- UsePrecompiledHeader="3"
+ UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_env_var_test_.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/$(ProjectName).lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
@@ -98,8 +87,6 @@ <Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
- Name="VCWebDeploymentTool"/>
- <Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
@@ -107,8 +94,8 @@ </Configurations>
<References>
<ProjectReference
- ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
- Name="gtest"/>
+ ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"
+ Name="gtest-md"/>
</References>
<Files>
<Filter
@@ -116,20 +103,18 @@ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
- RelativePath="..\test\gtest_env_var_test_.cc">
+ RelativePath="..\src\gtest_main.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""..";"..\include""
- UsePrecompiledHeader="0"/>
+ AdditionalIncludeDirectories=""..";"..\include""/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""..";"..\include""
- UsePrecompiledHeader="0"/>
+ AdditionalIncludeDirectories=""..";"..\include""/>
</FileConfiguration>
</File>
</Filter>
@@ -137,6 +122,42 @@ Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\include\gtest\internal\gtest-death-test-internal.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest-death-test.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-filepath.h">
+ </File>
+ <File
+ RelativePath="..\src\gtest-internal-inl.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-internal.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest-message.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-port.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest-spi.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\internal\gtest-string.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest_pred_impl.h">
+ </File>
+ <File
+ RelativePath="..\include\gtest\gtest_prod.h">
+ </File>
</Filter>
</Files>
<Globals>
diff --git a/gtest/msvc/gtest_main.vcproj b/gtest/msvc/gtest_main.vcproj index db2f617..1c8c58e 100644 --- a/gtest/msvc/gtest_main.vcproj +++ b/gtest/msvc/gtest_main.vcproj @@ -12,8 +12,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="">
@@ -26,7 +26,7 @@ RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
@@ -54,8 +54,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath=""..\include";".."">
@@ -65,7 +65,7 @@ RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
diff --git a/gtest/msvc/gtest_color_test_.vcproj b/gtest/msvc/gtest_prod_test-md.vcproj index e5b52ec..05b05d9 100644 --- a/gtest/msvc/gtest_color_test_.vcproj +++ b/gtest/msvc/gtest_prod_test-md.vcproj @@ -2,8 +2,8 @@ <VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
- Name="gtest_color_test_"
- ProjectGUID="{ABC5A7E8-072C-4A2D-B186-19EA5394B9C6}"
+ Name="gtest_prod_test-md"
+ ProjectGUID="{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}"
Keyword="Win32Proj">
<Platforms>
<Platform
@@ -12,8 +12,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -25,16 +25,16 @@ RuntimeLibrary="3"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_color_test_.exe"
+ OutputFile="$(OutDir)/gtest_prod_test.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/gtest_color_test_.pdb"
+ ProgramDatabaseFile="$(OutDir)/gtest_prod_test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
@@ -60,8 +60,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -70,13 +70,13 @@ RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_color_test_.exe"
+ OutputFile="$(OutDir)/gtest_prod_test.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
@@ -107,8 +107,8 @@ </Configurations>
<References>
<ProjectReference
- ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
- Name="gtest"/>
+ ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862033}"
+ Name="gtest_main-md"/>
</References>
<Files>
<Filter
@@ -116,7 +116,24 @@ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
- RelativePath="..\test\gtest_color_test_.cc">
+ RelativePath="..\test\gtest_prod_test.cc">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""..";"..\include""
+ UsePrecompiledHeader="0"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\test\production.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
@@ -137,6 +154,9 @@ Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath="..\test\production.h">
+ </File>
</Filter>
</Files>
<Globals>
diff --git a/gtest/msvc/gtest_prod_test.vcproj b/gtest/msvc/gtest_prod_test.vcproj index 9e31611..d1f6345 100644 --- a/gtest/msvc/gtest_prod_test.vcproj +++ b/gtest/msvc/gtest_prod_test.vcproj @@ -12,8 +12,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -25,7 +25,7 @@ RuntimeLibrary="3"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
@@ -60,8 +60,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -70,7 +70,7 @@ RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
diff --git a/gtest/msvc/gtest_uninitialized_test_.vcproj b/gtest/msvc/gtest_uninitialized_test_.vcproj deleted file mode 100644 index b6c1e71..0000000 --- a/gtest/msvc/gtest_uninitialized_test_.vcproj +++ /dev/null @@ -1,144 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="gtest_uninitialized_test_"
- ProjectGUID="{42B8A077-E162-4540-A688-246296ACAC1D}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="3"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_uninitialized_test_.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/gtest_uninitialized_test_.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- RuntimeLibrary="2"
- UsePrecompiledHeader="3"
- WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_uninitialized_test_.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- <ProjectReference
- ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
- Name="gtest"/>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
- <File
- RelativePath="..\test\gtest_uninitialized_test_.cc">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""..";"..\include""
- UsePrecompiledHeader="0"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""..";"..\include""
- UsePrecompiledHeader="0"/>
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/gtest/msvc/gtest_output_test_.vcproj b/gtest/msvc/gtest_unittest-md.vcproj index 6c73796..38a5e56 100644 --- a/gtest/msvc/gtest_output_test_.vcproj +++ b/gtest/msvc/gtest_unittest-md.vcproj @@ -2,8 +2,8 @@ <VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
- Name="gtest_output_test_"
- ProjectGUID="{A4903F73-ED6C-4972-863E-F7355EB0145E}"
+ Name="gtest_unittest-md"
+ ProjectGUID="{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}"
Keyword="Win32Proj">
<Platforms>
<Platform
@@ -12,8 +12,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -25,16 +25,16 @@ RuntimeLibrary="3"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_output_test_.exe"
+ OutputFile="$(OutDir)/gtest_unittest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/gtest_output_test_.pdb"
+ ProgramDatabaseFile="$(OutDir)/gtest_unittest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
@@ -60,8 +60,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -70,13 +70,13 @@ RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- OutputFile="$(OutDir)/gtest_output_test_.exe"
+ OutputFile="$(OutDir)/gtest_unittest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
@@ -107,8 +107,8 @@ </Configurations>
<References>
<ProjectReference
- ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
- Name="gtest"/>
+ ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862033}"
+ Name="gtest_main-md"/>
</References>
<Files>
<Filter
@@ -116,7 +116,7 @@ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
- RelativePath="..\test\gtest_output_test_.cc">
+ RelativePath="..\test\gtest_unittest.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
diff --git a/gtest/msvc/gtest_unittest.vcproj b/gtest/msvc/gtest_unittest.vcproj index 9350bef..3c8769e 100644 --- a/gtest/msvc/gtest_unittest.vcproj +++ b/gtest/msvc/gtest_unittest.vcproj @@ -12,8 +12,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -25,7 +25,7 @@ RuntimeLibrary="3"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
@@ -60,8 +60,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
+ OutputDirectory="$(SolutionName)/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -70,7 +70,7 @@ RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
- Detect64BitPortabilityProblems="TRUE"
+ Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
diff --git a/gtest/samples/sample10_unittest.cc b/gtest/samples/sample10_unittest.cc new file mode 100644 index 0000000..703ec6e --- /dev/null +++ b/gtest/samples/sample10_unittest.cc @@ -0,0 +1,145 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to use Google Test listener API to implement +// a primitive leak checker. + +#include <stdio.h> +#include <stdlib.h> + +#include <gtest/gtest.h> + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +namespace { + +// We will track memory used by this class. +class Water { + public: + // Normal Water declarations go here. + + // operator new and operator delete help us control water allocation. + void* operator new(size_t allocation_size) { + allocated_++; + return malloc(allocation_size); + } + + void operator delete(void* block, size_t allocation_size) { + allocated_--; + free(block); + } + + static int allocated() { return allocated_; } + + private: + static int allocated_; +}; + +int Water::allocated_ = 0; + +// This event listener monitors how many Water objects are created and +// destroyed by each test, and reports a failure if a test leaks some Water +// objects. It does this by comparing the number of live Water objects at +// the beginning of a test and at the end of a test. +class LeakChecker : public EmptyTestEventListener { + private: + // Called before a test starts. + virtual void OnTestStart(const TestInfo& test_info) { + initially_allocated_ = Water::allocated(); + } + + // Called after a test ends. + virtual void OnTestEnd(const TestInfo& test_info) { + int difference = Water::allocated() - initially_allocated_; + + // You can generate a failure in any event handler except + // OnTestPartResult. Just use an appropriate Google Test assertion to do + // it. + EXPECT_TRUE(difference <= 0) + << "Leaked " << difference << " unit(s) of Water!"; + } + + int initially_allocated_; +}; + +TEST(ListenersTest, DoesNotLeak) { + Water* water = new Water; + delete water; +} + +// This should fail when the --check_for_leaks command line flag is +// specified. +TEST(ListenersTest, LeaksWater) { + Water* water = new Water; + EXPECT_TRUE(water != NULL); +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool check_for_leaks = false; + if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 ) + check_for_leaks = true; + else + printf("%s\n", "Run this program with --check_for_leaks to enable " + "custom leak checking in the tests."); + + // If we are given the --check_for_leaks command line flag, installs the + // leak checker. + if (check_for_leaks) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + + // Adds the leak checker to the end of the test event listener list, + // after the default text output printer and the default XML report + // generator. + // + // The order is important - it ensures that failures generated in the + // leak checker's OnTestEnd() method are processed by the text and XML + // printers *before* their OnTestEnd() methods are called, such that + // they are attributed to the right test. Remember that a listener + // receives an OnXyzStart event *after* listeners preceding it in the + // list received that event, and receives an OnXyzEnd event *before* + // listeners preceding it. + // + // We don't need to worry about deleting the new listener later, as + // Google Test will do it. + listeners.Append(new LeakChecker); + } + return RUN_ALL_TESTS(); +} diff --git a/gtest/samples/sample9_unittest.cc b/gtest/samples/sample9_unittest.cc new file mode 100644 index 0000000..8944c47 --- /dev/null +++ b/gtest/samples/sample9_unittest.cc @@ -0,0 +1,160 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// This sample shows how to use Google Test listener API to implement +// an alternative console output and how to use the UnitTest reflection API +// to enumerate test cases and tests and to inspect their results. + +#include <stdio.h> + +#include <gtest/gtest.h> + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; + +namespace { + +// Provides alternative output mode which produces minimal amount of +// information about tests. +class TersePrinter : public EmptyTestEventListener { + private: + // Called before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) {} + + // Called after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) { + fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED"); + fflush(stdout); + } + + // Called before a test starts. + virtual void OnTestStart(const TestInfo& test_info) { + fprintf(stdout, + "*** Test %s.%s starting.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } + + // Called after a failed assertion or a SUCCESS(). + virtual void OnTestPartResult(const TestPartResult& test_part_result) { + fprintf(stdout, + "%s in %s:%d\n%s\n", + test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), + test_part_result.line_number(), + test_part_result.summary()); + fflush(stdout); + } + + // Called after a test ends. + virtual void OnTestEnd(const TestInfo& test_info) { + fprintf(stdout, + "*** Test %s.%s ending.\n", + test_info.test_case_name(), + test_info.name()); + fflush(stdout); + } +}; // class TersePrinter + +TEST(CustomOutputTest, PrintsMessage) { + printf("Printing something from the test body...\n"); +} + +TEST(CustomOutputTest, Succeeds) { + SUCCEED() << "SUCCEED() has been invoked from here"; +} + +TEST(CustomOutputTest, Fails) { + EXPECT_EQ(1, 2) + << "This test fails in order to demonstrate alternative failure messages"; +} + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + bool terse_output = false; + if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 ) + terse_output = true; + else + printf("%s\n", "Run this program with --terse_output to change the way " + "it prints its output."); + + UnitTest& unit_test = *UnitTest::GetInstance(); + + // If we are given the --terse_output command line flag, suppresses the + // standard output and attaches own result printer. + if (terse_output) { + TestEventListeners& listeners = unit_test.listeners(); + + // Removes the default console output listener from the list so it will + // not receive events from Google Test and won't print any output. Since + // this operation transfers ownership of the listener to the caller we + // have to delete it as well. + delete listeners.Release(listeners.default_result_printer()); + + // Adds the custom output listener to the list. It will now receive + // events from Google Test and print the alternative output. We don't + // have to worry about deleting it since Google Test assumes ownership + // over it after adding it to the list. + listeners.Append(new TersePrinter); + } + int ret_val = RUN_ALL_TESTS(); + + // This is an example of using the UnitTest reflection API to inspect test + // results. Here we discount failures from the tests we expected to fail. + int unexpectedly_failed_tests = 0; + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + // Counts failed tests that were not meant to fail (those without + // 'Fails' in the name). + if (test_info.result()->Failed() && + strcmp(test_info.name(), "Fails") != 0) { + unexpectedly_failed_tests++; + } + } + } + + // Test that were meant to fail should not affect the test program outcome. + if (unexpectedly_failed_tests == 0) + ret_val = 0; + + return ret_val; +} diff --git a/gtest/scons/SConscript b/gtest/scons/SConscript index 8fbd5f5..26fa5fb 100644 --- a/gtest/scons/SConscript +++ b/gtest/scons/SConscript @@ -1,5 +1,4 @@ -#!/usr/bin/python2.4 -# +# -*- Python -*- # Copyright 2008 Google Inc. All Rights Reserved. # # Redistribution and use in source and binary forms, with or without @@ -96,29 +95,9 @@ import os ############################################################ # Environments for building the targets, sorted by name. -def NewEnvironment(env, type): - """Copies environment and gives it suffix for names of targets built in it.""" - - if type: - suffix = '_' + type - else: - suffix = '' - - new_env = env.Clone() - new_env['OBJ_SUFFIX'] = suffix - return new_env; - - -def Remove(env, attribute, value): - """Removes the given attribute value from the environment.""" - - attribute_values = env[attribute] - if value in attribute_values: - attribute_values.remove(value) - +Import('env', 'EnvCreator') -Import('env') -env = NewEnvironment(env, '') +env = EnvCreator.Create(env) # Note: The relative paths in SConscript files are relative to the location # of the SConscript file itself. To make a path relative to the location of @@ -133,51 +112,16 @@ env = NewEnvironment(env, '') # file is one directory deeper than the gtest directory. env.Prepend(CPPPATH = ['..', '../include']) -env_use_own_tuple = NewEnvironment(env, 'use_own_tuple') -env_use_own_tuple.Append(CPPDEFINES = 'GTEST_USE_OWN_TR1_TUPLE=1') - -# Needed to allow gtest_unittest.cc, which triggers a gcc warning when -# testing EXPECT_EQ(NULL, ptr), to compile. -env_warning_ok = NewEnvironment(env, 'warning_ok') -if env_warning_ok['PLATFORM'] == 'win32': - Remove(env_warning_ok, 'CCFLAGS', '-WX') -else: - Remove(env_warning_ok, 'CCFLAGS', '-Werror') - -env_with_exceptions = NewEnvironment(env_warning_ok, 'ex') -if env_with_exceptions['PLATFORM'] == 'win32': - env_with_exceptions.Append(CCFLAGS=['/EHsc']) - env_with_exceptions.Append(CPPDEFINES='_HAS_EXCEPTIONS=1') - # Undoes the _TYPEINFO_ hack, which is unnecessary and only creates - # trouble when exceptions are enabled. - Remove(env_with_exceptions, 'CPPDEFINES', '_TYPEINFO_') - Remove(env_with_exceptions, 'CPPDEFINES', '_HAS_EXCEPTIONS=0') -else: - env_with_exceptions.Append(CCFLAGS='-fexceptions') - Remove(env_with_exceptions, 'CCFLAGS', '-fno-exceptions') - -# We need to disable some optimization flags for some tests on -# Windows; otherwise the redirection of stdout does not work -# (apparently because of a compiler bug). -env_less_optimized = NewEnvironment(env, 'less_optimized') -if env_less_optimized['PLATFORM'] == 'win32': - for flag in ['/O1', '/Os', '/Og', '/Oy']: - Remove(env_less_optimized, 'LINKFLAGS', flag) - -# Assuming POSIX-like environment with GCC. -# TODO(vladl@google.com): sniff presence of pthread_atfork instead of -# selecting on a platform. -env_with_threads = NewEnvironment(env, 'with_threads') -if env_with_threads['PLATFORM'] != 'win32': - env_with_threads.Append(CCFLAGS=['-pthread']) - env_with_threads.Append(LINKFLAGS=['-pthread']) - -env_without_rtti = NewEnvironment(env_warning_ok, 'no_rtti') -if env_without_rtti['PLATFORM'] == 'win32': - env_without_rtti.Append(CCFLAGS=['/GR-']) -else: - env_without_rtti.Append(CCFLAGS=['-fno-rtti']) - env_without_rtti.Append(CPPDEFINES='GTEST_HAS_RTTI=0') +env_use_own_tuple = EnvCreator.Create(env, EnvCreator.UseOwnTuple) +env_less_optimized = EnvCreator.Create(env, EnvCreator.LessOptimized) +env_with_threads = EnvCreator.Create(env, EnvCreator.WithThreads) +# The following environments are used to compile gtest_unittest.cc, which +# triggers a warning in all but the most recent GCC versions when compiling +# the EXPECT_EQ(NULL, ptr) statement. +env_warning_ok = EnvCreator.Create(env, EnvCreator.WarningOk) +env_with_exceptions = EnvCreator.Create(env_warning_ok, + EnvCreator.WithExceptions) +env_without_rtti = EnvCreator.Create(env_warning_ok, EnvCreator.NoRtti) ############################################################ # Helpers for creating build targets. @@ -318,8 +262,10 @@ GtestTest(env, 'gtest_list_tests_unittest_', gtest) GtestTest(env, 'gtest_throw_on_failure_test_', gtest) GtestTest(env, 'gtest_xml_outfile1_test_', gtest_main) GtestTest(env, 'gtest_xml_outfile2_test_', gtest_main) -GtestTest(env, 'gtest_xml_output_unittest_', gtest_main) +GtestTest(env, 'gtest_xml_output_unittest_', gtest) GtestTest(env, 'gtest-unittest-api_test', gtest) +GtestTest(env, 'gtest-listener_test', gtest) +GtestTest(env, 'gtest_shuffle_test_', gtest) ############################################################ # Tests targets using custom environments. @@ -363,13 +309,15 @@ if env.get('GTEST_BUILD_SAMPLES', False): GtestSample(env, 'sample6_unittest') GtestSample(env, 'sample7_unittest') GtestSample(env, 'sample8_unittest') + GtestSample(env, 'sample9_unittest') + GtestSample(env, 'sample10_unittest') # These exports are used by Google Mock. gtest_exports = {'gtest': gtest, 'gtest_ex': gtest_ex, 'gtest_no_rtti': gtest_no_rtti, 'gtest_use_own_tuple': gtest_use_own_tuple, - 'NewEnvironment': NewEnvironment, + 'EnvCreator': EnvCreator, 'GtestObject': GtestObject, 'GtestBinary': GtestBinary, 'GtestTest': GtestTest} diff --git a/gtest/scons/SConstruct b/gtest/scons/SConstruct new file mode 100644 index 0000000..1f2f37f --- /dev/null +++ b/gtest/scons/SConstruct @@ -0,0 +1,61 @@ +# -*- Python -*- +# Copyright 2008 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: joi@google.com (Joi Sigurdsson) +# Author: vladl@google.com (Vlad Losev) +# +# Base build file for Google Test Tests. +# +# Usage: +# cd to the directory with this file, then +# ./scons.py [OPTIONS] +# +# where frequently used command-line options include: +# -h print usage help. +# BUILD=all build all build types. +# BUILD=win-opt build the given build type. + +EnsurePythonVersion(2, 3) + +sconstruct_helper = SConscript('SConstruct.common') + +sconstruct_helper.Initialize(build_root_path='..', + support_multiple_win_builds=False) + +win_base = sconstruct_helper.MakeWinBaseEnvironment() + +if win_base.get('MSVS_VERSION', None) == '7.1': + sconstruct_helper.AllowVc71StlWithoutExceptions(win_base) + +sconstruct_helper.MakeWinDebugEnvironment(win_base, 'win-dbg') +sconstruct_helper.MakeWinOptimizedEnvironment(win_base, 'win-opt') + +sconstruct_helper.ConfigureGccEnvironments() + +sconstruct_helper.BuildSelectedEnvironments() diff --git a/gtest/scons/SConstruct.common b/gtest/scons/SConstruct.common new file mode 100644 index 0000000..2445beb --- /dev/null +++ b/gtest/scons/SConstruct.common @@ -0,0 +1,356 @@ +# -*- Python -*- +# Copyright 2008 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: joi@google.com (Joi Sigurdsson) +# Author: vladl@google.com (Vlad Losev) +# +# Shared SCons utilities for building Google Test inside and outside of +# Google's environment. +# + +EnsurePythonVersion(2, 3) + + +BUILD_DIR_PREFIX = 'build' + + +class SConstructHelper: + def __init__(self): + # A dictionary to look up an environment by its name. + self.env_dict = {} + + def Initialize(self, build_root_path, support_multiple_win_builds=False): + test_env = Environment() + platform = test_env['PLATFORM'] + if platform == 'win32': + if support_multiple_win_builds: + available_build_types = ['win-dbg8', 'win-opt8', 'win-dbg', 'win-opt'] + else: + available_build_types = ['win-dbg', 'win-opt'] + elif platform == 'darwin': # MacOSX + available_build_types = ['mac-dbg', 'mac-opt'] + else: + available_build_types = ['dbg', 'opt'] # Assuming POSIX-like environment + # with GCC by default. + + vars = Variables() + vars.Add(ListVariable('BUILD', 'Build type', available_build_types[0], + available_build_types)) + vars.Add(BoolVariable('GTEST_BUILD_SAMPLES', 'Build samples', False)) + + # Create base environment. + self.env_base = Environment(variables=vars, + BUILD_MODE={'BUILD' : '"${BUILD}"'}) + + # Leave around a variable pointing at the build root so that SConscript + # files from outside our project root can find their bearings. Trick + # borrowed from Hammer in Software Construction Toolkit + # (http://code.google.com/p/swtoolkit/); if/when we switch to using the + # Hammer idioms instead of just Hammer's version of SCons, we should be + # able to remove this line. + self.env_base['SOURCE_ROOT'] = self.env_base.Dir(build_root_path) + + # And another that definitely always points to the project root. + self.env_base['PROJECT_ROOT'] = self.env_base.Dir('.').abspath + + # Enable scons -h + Help(vars.GenerateHelpText(self.env_base)) + + class EnvCreator: + """Creates new customized environments from a base one.""" + + def _Remove(cls, env, attribute, value): + """Removes the given attribute value from the environment.""" + + attribute_values = env[attribute] + if value in attribute_values: + attribute_values.remove(value) + _Remove = classmethod(_Remove) + + def Create(cls, base_env, modifier=None): + # User should NOT create more than one environment with the same + # modifier (including None). + env = base_env.Clone() + if modifier: + modifier(env) + else: + env['OBJ_SUFFIX'] = '' # Default suffix for unchanged environment. + return env; + Create = classmethod(Create) + + # Each of the following methods modifies the environment for a particular + # purpose and can be used by clients for creating new environments. Each + # one needs to set the OBJ_SUFFIX variable to a unique suffix to + # differentiate targets built with that environment. Otherwise, SCons may + # complain about same target built with different settings. + + def UseOwnTuple(cls, env): + """Instructs Google Test to use its internal implementation of tuple.""" + + env['OBJ_SUFFIX'] = '_use_own_tuple' + env.Append(CPPDEFINES = 'GTEST_USE_OWN_TR1_TUPLE=1') + UseOwnTuple = classmethod(UseOwnTuple) + + def WarningOk(cls, env): + """Does not treat warnings as errors. + + Necessary for compiling gtest_unittest.cc, which triggers a gcc + warning when testing EXPECT_EQ(NULL, ptr).""" + + env['OBJ_SUFFIX'] = '_warning_ok' + if env['PLATFORM'] == 'win32': + cls._Remove(env, 'CCFLAGS', '-WX') + else: + cls._Remove(env, 'CCFLAGS', '-Werror') + WarningOk = classmethod(WarningOk) + + def WithExceptions(cls, env): + """Re-enables exceptions.""" + + env['OBJ_SUFFIX'] = '_ex' + if env['PLATFORM'] == 'win32': + env.Append(CCFLAGS=['/EHsc']) + env.Append(CPPDEFINES='_HAS_EXCEPTIONS=1') + # Undoes the _TYPEINFO_ hack, which is unnecessary and only creates + # trouble when exceptions are enabled. + cls._Remove(env, 'CPPDEFINES', '_TYPEINFO_') + cls._Remove(env, 'CPPDEFINES', '_HAS_EXCEPTIONS=0') + else: + env.Append(CCFLAGS='-fexceptions') + cls._Remove(env, 'CCFLAGS', '-fno-exceptions') + WithExceptions = classmethod(WithExceptions) + + def LessOptimized(cls, env): + """Disables certain optimizations on Windows. + + We need to disable some optimization flags for some tests on + Windows; otherwise the redirection of stdout does not work + (apparently because of a compiler bug).""" + + env['OBJ_SUFFIX'] = '_less_optimized' + if env['PLATFORM'] == 'win32': + for flag in ['/O1', '/Os', '/Og', '/Oy']: + cls._Remove(env, 'LINKFLAGS', flag) + LessOptimized = classmethod(LessOptimized) + + def WithThreads(cls, env): + """Allows use of threads. + + Currently only enables pthreads under GCC.""" + + env['OBJ_SUFFIX'] = '_with_threads' + if env['PLATFORM'] != 'win32': + # Assuming POSIX-like environment with GCC. + # TODO(vladl@google.com): sniff presence of pthread_atfork instead of + # selecting on a platform. + env.Append(CCFLAGS=['-pthread']) + env.Append(LINKFLAGS=['-pthread']) + WithThreads = classmethod(WithThreads) + + def NoRtti(cls, env): + """Disables RTTI support.""" + + env['OBJ_SUFFIX'] = '_no_rtti' + if env['PLATFORM'] == 'win32': + env.Append(CCFLAGS=['/GR-']) + else: + env.Append(CCFLAGS=['-fno-rtti']) + env.Append(CPPDEFINES='GTEST_HAS_RTTI=0') + NoRtti = classmethod(NoRtti) + + def AllowVc71StlWithoutExceptions(self, env): + env.Append( + CPPDEFINES = [# needed for using some parts of STL with exception + # disabled. The scoop is given here, with comments + # from P.J. Plauger at + # http://groups.google.com/group/microsoft.public.vc.stl/browse_thread/thread/5e719833c6bdb177?q=_HAS_EXCEPTIONS+using+namespace+std&pli=1 + '_TYPEINFO_']) + + def MakeWinBaseEnvironment(self): + win_base = self.env_base.Clone( + platform='win32', + CCFLAGS=['-GS', # Enable buffer security check + '-W4', # Warning level + + # Disables warnings that are either uninteresting or + # hard to fix. + + '-WX', # Treat warning as errors + #'-GR-', # Disable runtime type information + '-RTCs', # Enable stack-frame run-time error checks + '-RTCu', # Report when variable used without init. + #'-EHs', # enable C++ EH (no SEH exceptions) + '-nologo', # Suppress logo line + '-J', # All chars unsigned + #'-Wp64', # Detect 64-bit portability issues. This + # flag has been deprecated by VS 2008. + '-Zi', # Produce debug information in PDB files. + ], + CCPDBFLAGS='', + CPPDEFINES=['_UNICODE', 'UNICODE', + 'WIN32', '_WIN32', + 'STRICT', + 'WIN32_LEAN_AND_MEAN', + '_HAS_EXCEPTIONS=0', + ], + LIBPATH=['#/$MAIN_DIR/lib'], + LINKFLAGS=['-MACHINE:x86', # Enable safe SEH (not supp. on x64) + '-DEBUG', # Generate debug info + '-NOLOGO', # Suppress logo line + ], + # All strings in string tables zero terminated. + RCFLAGS=['-n']) + + return win_base + + def SetBuildNameAndDir(self, env, name): + env['BUILD_NAME'] = name; + env['BUILD_DIR'] = '%s/%s' % (BUILD_DIR_PREFIX, name) + self.env_dict[name] = env + + def MakeWinDebugEnvironment(self, base_environment, name): + """Takes a VC71 or VC80 base environment and adds debug settings.""" + debug_env = base_environment.Clone() + self.SetBuildNameAndDir(debug_env, name) + debug_env.Append( + CCFLAGS = ['-Od', # Disable optimizations + '-MTd', # Multithreaded, static link (debug) + # Path for PDB files + '-Fd%s\\' % debug_env.Dir(debug_env['BUILD_DIR']), + ], + CPPDEFINES = ['DEBUG', + '_DEBUG', + ], + LIBPATH = [], + LINKFLAGS = ['-INCREMENTAL:yes', + '/OPT:NOICF', + ] + ) + return debug_env + + def MakeWinOptimizedEnvironment(self, base_environment, name): + """Takes a VC71 or VC80 base environment and adds release settings.""" + optimized_env = base_environment.Clone() + self.SetBuildNameAndDir(optimized_env, name) + optimized_env.Append( + CCFLAGS = ['-GL', # Enable link-time code generation (/GL) + '-GF', # Enable String Pooling (/GF) + '-MT', # Multithreaded, static link + # Path for PDB files + '-Fd%s\\' % optimized_env.Dir(optimized_env['BUILD_DIR']), + + # Favor small code (this is /O1 minus /Og) + '-Os', + '-Oy', + '-Ob2', + '-Gs', + '-GF', + '-Gy', + ], + CPPDEFINES = ['NDEBUG', + '_NDEBUG', + ], + LIBPATH = [], + ARFLAGS = ['-LTCG'], # Link-time Code Generation + LINKFLAGS = ['-LTCG', # Link-time Code Generation + '-OPT:REF', # Optimize by reference. + '-OPT:ICF=32', # Optimize by identical COMDAT folding + '-OPT:NOWIN98', # Optimize by not aligning section for + # Win98 + '-INCREMENTAL:NO', # No incremental linking as we don't + # want padding bytes in release build. + ], + ) + return optimized_env + + def AddGccFlagsTo(self, env, optimized): + env.Append(CCFLAGS=['-fno-exceptions', + '-Wall', + '-Werror', + ]) + if optimized: + env.Append(CCFLAGS=['-O2'], CPPDEFINES=['NDEBUG', '_NDEBUG']) + else: + env.Append(CCFLAGS=['-g'], CPPDEFINES=['DEBUG', '_DEBUG']) + + def ConfigureGccEnvironments(self): + # Mac environments. + mac_base = self.env_base.Clone(platform='darwin') + + mac_dbg = mac_base.Clone() + self.AddGccFlagsTo(mac_dbg, optimized=False) + self.SetBuildNameAndDir(mac_dbg, 'mac-dbg') + + mac_opt = mac_base.Clone() + self.AddGccFlagsTo(mac_opt, optimized=True) + self.SetBuildNameAndDir(mac_opt, 'mac-opt') + + # Generic GCC environments. + gcc_dbg = self.env_base.Clone() + self.AddGccFlagsTo(gcc_dbg, optimized=False) + self.SetBuildNameAndDir(gcc_dbg, 'dbg') + + gcc_opt = self.env_base.Clone() + self.AddGccFlagsTo(gcc_opt, optimized=True) + self.SetBuildNameAndDir(gcc_opt, 'opt') + + def BuildSelectedEnvironments(self): + EnvCreator = SConstructHelper.EnvCreator + Export('EnvCreator') + # Build using whichever environments the 'BUILD' option selected + for build_name in self.env_base['BUILD']: + print 'BUILDING %s' % build_name + env = self.env_dict[build_name] + + # Make sure SConscript files can refer to base build dir + env['MAIN_DIR'] = env.Dir(env['BUILD_DIR']) + + #print 'CCFLAGS: %s' % env.subst('$CCFLAGS') + #print 'LINK: %s' % env.subst('$LINK') + #print 'AR: %s' % env.subst('$AR') + #print 'CC: %s' % env.subst('$CC') + #print 'CXX: %s' % env.subst('$CXX') + #print 'LIBPATH: %s' % env.subst('$LIBPATH') + #print 'ENV:PATH: %s' % env['ENV']['PATH'] + #print 'ENV:INCLUDE: %s' % env['ENV']['INCLUDE'] + #print 'ENV:LIB: %s' % env['ENV']['LIB'] + #print 'ENV:TEMP: %s' % env['ENV']['TEMP'] + + Export('env') + # Invokes SConscript with variant_dir being build/<config name>. + # Counter-intuitively, src_dir is relative to the build dir and has + # to be '..' to point to the scons directory. + SConscript('SConscript', + src_dir='..', + variant_dir=env['BUILD_DIR'], + duplicate=0) + + +sconstruct_helper = SConstructHelper() +Return('sconstruct_helper') diff --git a/gtest/scripts/gen_gtest_pred_impl.py b/gtest/scripts/gen_gtest_pred_impl.py index d1b2f25..8307134 100755 --- a/gtest/scripts/gen_gtest_pred_impl.py +++ b/gtest/scripts/gen_gtest_pred_impl.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2.4 +#!/usr/bin/env python # # Copyright 2006, Google Inc. # All rights reserved. diff --git a/gtest/src/gtest-death-test.cc b/gtest/src/gtest-death-test.cc index 02ce48d..106b01c 100644 --- a/gtest/src/gtest-death-test.cc +++ b/gtest/src/gtest-death-test.cc @@ -220,12 +220,12 @@ void DeathTestAbort(const String& message) { // fails. #define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ - if (!(expression)) { \ - DeathTestAbort(::testing::internal::String::Format(\ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ "CHECK failed: File %s, line %d: %s", \ __FILE__, __LINE__, #expression)); \ } \ - } while (0) + } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return @@ -241,11 +241,11 @@ void DeathTestAbort(const String& message) { gtest_retval = (expression); \ } while (gtest_retval == -1 && errno == EINTR); \ if (gtest_retval == -1) { \ - DeathTestAbort(::testing::internal::String::Format(\ + DeathTestAbort(::testing::internal::String::Format( \ "CHECK failed: File %s, line %d: %s != -1", \ __FILE__, __LINE__, #expression)); \ } \ - } while (0) + } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. String GetLastErrnoDescription() { @@ -269,13 +269,11 @@ static void FailFromInternalError(int fd) { } while (num_read == -1 && errno == EINTR); if (num_read == 0) { - GTEST_LOG_(FATAL, error); + GTEST_LOG_(FATAL) << error.GetString(); } else { const int last_error = errno; - const String message = GetLastErrnoDescription(); - GTEST_LOG_(FATAL, - Message() << "Error while reading death test internal: " - << message << " [" << last_error << "]"); + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; } } @@ -397,15 +395,13 @@ void DeathTestImpl::ReadAndInterpretStatusByte() { FailFromInternalError(read_fd()); // Does not return. break; default: - GTEST_LOG_(FATAL, - Message() << "Death test child process reported " - << "unexpected status byte (" - << static_cast<unsigned int>(flag) << ")"); + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast<unsigned int>(flag) << ")"; } } else { - GTEST_LOG_(FATAL, - Message() << "Read from death test child process failed: " - << GetLastErrnoDescription()); + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); } GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); set_read_fd(-1); @@ -469,7 +465,8 @@ bool DeathTestImpl::Passed(bool status_ok) { break; case DIED: if (status_ok) { - if (RE::PartialMatch(error_message.c_str(), *regex())) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { success = true; } else { buffer << " Result: died but not with expected error.\n" @@ -483,8 +480,8 @@ bool DeathTestImpl::Passed(bool status_ok) { break; case IN_PROGRESS: default: - GTEST_LOG_(FATAL, - "DeathTest::Passed somehow called before conclusion of test"); + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; } DeathTest::set_last_death_test_message(buffer.GetString()); @@ -584,8 +581,8 @@ int WindowsDeathTest::Wait() { WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), INFINITE)); DWORD status; - GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), - &status)); + GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status) + != FALSE); child_handle_.Reset(); set_status(static_cast<int>(status)); return this->status(); @@ -615,9 +612,10 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() { SECURITY_ATTRIBUTES handles_are_inheritable = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; HANDLE read_handle, write_handle; - GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle, - &handles_are_inheritable, - 0)); // Default buffer size. + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), O_RDONLY)); write_handle_.Reset(write_handle); @@ -680,7 +678,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() { NULL, // Inherit the parent's environment. UnitTest::GetInstance()->original_working_dir(), &startup_info, - &process_info)); + &process_info) != FALSE); child_handle_.Reset(process_info.hProcess); ::CloseHandle(process_info.hThread); set_spawned(true); @@ -740,7 +738,7 @@ class NoExecDeathTest : public ForkingDeathTest { DeathTest::TestRole NoExecDeathTest::AssumeRole() { const size_t thread_count = GetThreadCount(); if (thread_count != 1) { - GTEST_LOG_(WARNING, DeathTestThreadWarning(thread_count)); + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); } int pipe_fd[2]; @@ -767,6 +765,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { // concurrent writes to the log files. We capture stderr in the parent // process and append the child process' output to a log. LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); @@ -1042,7 +1043,7 @@ static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; ::std::string::size_type pos = 0; - while (true) { + while (::testing::internal::AlwaysTrue()) { const ::std::string::size_type colon = str.find(delimiter, pos); if (colon == ::std::string::npos) { parsed.push_back(str.substr(pos)); diff --git a/gtest/src/gtest-filepath.cc b/gtest/src/gtest-filepath.cc index f966352..515d61c 100644 --- a/gtest/src/gtest-filepath.cc +++ b/gtest/src/gtest-filepath.cc @@ -34,7 +34,7 @@ #include <stdlib.h> -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE #include <windows.h> #elif GTEST_OS_WINDOWS #include <direct.h> @@ -45,7 +45,7 @@ #else #include <limits.h> #include <climits> // Some Linux distributions define PATH_MAX here. -#endif // _WIN32_WCE or _WIN32 +#endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS #define GTEST_PATH_MAX_ _MAX_PATH @@ -65,7 +65,7 @@ namespace internal { #if GTEST_OS_WINDOWS const char kPathSeparator = '\\'; const char kPathSeparatorString[] = "\\"; -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. @@ -74,7 +74,7 @@ const char kCurrentDirectoryString[] = "\\"; const DWORD kInvalidFileAttributes = 0xffffffff; #else const char kCurrentDirectoryString[] = ".\\"; -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kPathSeparatorString[] = "/"; @@ -83,9 +83,9 @@ const char kCurrentDirectoryString[] = "./"; // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { -#ifdef _WIN32_WCE -// Windows CE doesn't have a current directory, so we just return -// something reasonable. +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; @@ -93,7 +93,7 @@ FilePath FilePath::GetCurrentDir() { #else char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); -#endif +#endif // GTEST_OS_WINDOWS_MOBILE } // Returns a copy of the FilePath with the case-insensitive extension removed. @@ -103,7 +103,7 @@ FilePath FilePath::GetCurrentDir() { FilePath FilePath::RemoveExtension(const char* extension) const { String dot_extension(String::Format(".%s", extension)); if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { - return FilePath(String(pathname_.c_str(), pathname_.GetLength() - 4)); + return FilePath(String(pathname_.c_str(), pathname_.length() - 4)); } return *this; } @@ -169,7 +169,7 @@ FilePath FilePath::ConcatPaths(const FilePath& directory, // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. bool FilePath::FileOrDirectoryExists() const { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; @@ -177,7 +177,7 @@ bool FilePath::FileOrDirectoryExists() const { #else posix::StatStruct file_stat; return posix::Stat(pathname_.c_str(), &file_stat) == 0; -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE } // Returns true if pathname describes a directory in the file-system @@ -193,7 +193,7 @@ bool FilePath::DirectoryExists() const { const FilePath& path(*this); #endif -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; @@ -205,7 +205,7 @@ bool FilePath::DirectoryExists() const { posix::StatStruct file_stat; result = posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat); -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE return result; } @@ -217,7 +217,7 @@ bool FilePath::IsRootDirectory() const { // TODO(wan@google.com): on Windows a network share like // \\server\share can be a root directory, although it cannot be the // current directory. Handle this properly. - return pathname_.GetLength() == 3 && IsAbsolutePath(); + return pathname_.length() == 3 && IsAbsolutePath(); #else return pathname_ == kPathSeparatorString; #endif @@ -227,7 +227,7 @@ bool FilePath::IsRootDirectory() const { bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); #if GTEST_OS_WINDOWS - return pathname_.GetLength() >= 3 && + return pathname_.length() >= 3 && ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && @@ -271,7 +271,7 @@ bool FilePath::CreateDirectoriesRecursively() const { return false; } - if (pathname_.GetLength() == 0 || this->DirectoryExists()) { + if (pathname_.length() == 0 || this->DirectoryExists()) { return true; } @@ -284,18 +284,17 @@ bool FilePath::CreateDirectoriesRecursively() const { // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool FilePath::CreateFolder() const { -#if GTEST_OS_WINDOWS -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); int result = CreateDirectory(unicode, NULL) ? 0 : -1; delete [] unicode; -#else +#elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); -#endif // !WIN32_WCE #else int result = mkdir(pathname_.c_str(), 0777); -#endif // _WIN32 +#endif // GTEST_OS_WINDOWS_MOBILE + if (result == -1) { return this->DirectoryExists(); // An error is OK if the directory exists. } @@ -307,7 +306,7 @@ bool FilePath::CreateFolder() const { // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { return pathname_.EndsWith(kPathSeparatorString) - ? FilePath(String(pathname_.c_str(), pathname_.GetLength() - 1)) + ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) : *this; } @@ -320,9 +319,9 @@ void FilePath::Normalize() { return; } const char* src = pathname_.c_str(); - char* const dest = new char[pathname_.GetLength() + 1]; + char* const dest = new char[pathname_.length() + 1]; char* dest_ptr = dest; - memset(dest_ptr, 0, pathname_.GetLength() + 1); + memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { *dest_ptr++ = *src; diff --git a/gtest/src/gtest-internal-inl.h b/gtest/src/gtest-internal-inl.h index 189852e..47aec22 100644 --- a/gtest/src/gtest-internal-inl.h +++ b/gtest/src/gtest-internal-inl.h @@ -277,7 +277,7 @@ class Vector { // is created using the copy constructor, and then stored in the // Vector. Changes made to the element in the Vector doesn't affect // the source object, and vice versa. - void PushBack(const E & element) { Insert(element, size_); } + void PushBack(const E& element) { Insert(element, size_); } // Adds an element to the beginning of this Vector. void PushFront(const E& element) { Insert(element, 0); } @@ -369,7 +369,7 @@ class Vector { return NULL; } - // Returns the i-th element of the list, or aborts the program if i + // Returns the i-th element of the Vector, or aborts the program if i // is not in range [0, size()). const E& GetElement(int i) const { GTEST_CHECK_(0 <= i && i < size_) @@ -379,13 +379,84 @@ class Vector { return *(elements_[i]); } - // Returns the i-th element of the list, or default_value if i is not + // Returns a mutable reference to the i-th element of the Vector, or + // aborts the program if i is not in range [0, size()). + E& GetMutableElement(int i) { + GTEST_CHECK_(0 <= i && i < size_) + << "Invalid Vector index " << i << ": must be in range [0, " + << (size_ - 1) << "]."; + + return *(elements_[i]); + } + + // Returns the i-th element of the Vector, or default_value if i is not // in range [0, size()). E GetElementOr(int i, E default_value) const { return (i < 0 || i >= size_) ? default_value : *(elements_[i]); } + // Swaps the i-th and j-th elements of the Vector. Crashes if i or + // j is invalid. + void Swap(int i, int j) { + GTEST_CHECK_(0 <= i && i < size_) + << "Invalid first swap element " << i << ": must be in range [0, " + << (size_ - 1) << "]."; + GTEST_CHECK_(0 <= j && j < size_) + << "Invalid second swap element " << j << ": must be in range [0, " + << (size_ - 1) << "]."; + + E* const temp = elements_[i]; + elements_[i] = elements_[j]; + elements_[j] = temp; + } + + // Performs an in-place shuffle of a range of this Vector's nodes. + // 'begin' and 'end' are element indices as an STL-style range; + // i.e. [begin, end) are shuffled, where 'end' == size() means to + // shuffle to the end of the Vector. + void ShuffleRange(internal::Random* random, int begin, int end) { + GTEST_CHECK_(0 <= begin && begin <= size_) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size_ << "]."; + GTEST_CHECK_(begin <= end && end <= size_) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size_ << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + Swap(selected, last_in_range); + } + } + + // Performs an in-place shuffle of this Vector's nodes. + void Shuffle(internal::Random* random) { + ShuffleRange(random, 0, size()); + } + + // Returns a copy of this Vector. + Vector* Clone() const { + Vector* const clone = new Vector; + clone->Reserve(size_); + for (int i = 0; i < size_; i++) { + clone->PushBack(GetElement(i)); + } + return clone; + } + private: + // Makes sure this Vector's capacity is at least the given value. + void Reserve(int new_capacity) { + if (new_capacity <= capacity_) + return; + + capacity_ = new_capacity; + elements_ = static_cast<E**>( + realloc(elements_, capacity_*sizeof(elements_[0]))); + } + // Grows the buffer if it is not big enough to hold one more element. void GrowIfNeeded() { if (size_ < capacity_) @@ -397,9 +468,7 @@ class Vector { const int new_capacity = 3*(capacity_/2 + 1); GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow? << "Cannot grow a Vector with " << capacity_ << " elements already."; - capacity_ = new_capacity; - elements_ = static_cast<E**>( - realloc(elements_, capacity_*sizeof(elements_[0]))); + Reserve(new_capacity); } // Moves the give consecutive elements to a new index in the Vector. @@ -491,11 +560,6 @@ class TestInfoImpl { // deletes it. void Run(); - // Calls the given TestInfo object's Run() method. - static void RunTest(TestInfo * test_info) { - test_info->impl()->Run(); - } - // Clears the test result. void ClearResult() { result_.Clear(); } @@ -606,7 +670,7 @@ class OsStackTraceGetterInterface { // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: - OsStackTraceGetter() {} + OsStackTraceGetter() : caller_frame_(NULL) {} virtual String CurrentStackTrace(int max_depth, int skip_count); virtual void UponLeavingGTest(); @@ -738,9 +802,20 @@ class UnitTestImpl { // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const { - return test_cases_.GetElementOr(i, NULL); + const int index = test_case_indices_.GetElementOr(i, -1); + return index < 0 ? NULL : test_cases_.GetElement(i); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = test_case_indices_.GetElementOr(i, -1); + return index < 0 ? NULL : test_cases_.GetElement(index); } + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* current_test_result(); @@ -748,18 +823,6 @@ class UnitTestImpl { // Returns the TestResult for the ad hoc test. const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } - // Sets the unit test result printer. - // - // Does nothing if the input and the current printer object are the - // same; otherwise, deletes the old printer object and makes the - // input the current printer. - void set_result_printer(UnitTestEventListenerInterface* result_printer); - - // Returns the current unit test result printer if it is not NULL; - // otherwise, creates an appropriate result printer, makes it the - // current printer, and returns it. - UnitTestEventListenerInterface* result_printer(); - // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter @@ -895,9 +958,6 @@ class UnitTestImpl { return &environments_in_reverse_order_; } - internal::Vector<TestCase*>* test_cases() { return &test_cases_; } - const internal::Vector<TestCase*>* test_cases() const { return &test_cases_; } - // Getters for the per-thread Google Test trace stack. internal::Vector<TraceInfo>* gtest_trace_stack() { return gtest_trace_stack_.pointer(); @@ -907,9 +967,13 @@ class UnitTestImpl { } #if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. const InternalRunDeathTestFlag* internal_run_death_test_flag() const { return internal_run_death_test_flag_.get(); } @@ -919,12 +983,35 @@ class UnitTestImpl { return death_test_factory_.get(); } + void SuppressTestEventsIfInSubprocess(); + friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST - // Gets the random seed used at the start of the current test run. + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. int random_seed() const { return random_seed_; } + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + private: friend class ::testing::UnitTest; @@ -956,7 +1043,15 @@ class UnitTestImpl { internal::Vector<Environment*> environments_; internal::Vector<Environment*> environments_in_reverse_order_; - internal::Vector<TestCase*> test_cases_; // The vector of TestCases. + // The vector of TestCases in their original order. It owns the + // elements in the vector. + internal::Vector<TestCase*> test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + internal::Vector<int> test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized @@ -992,11 +1087,9 @@ class UnitTestImpl { // test, and records the result in ad_hoc_test_result_. TestResult ad_hoc_test_result_; - // The unit test result printer. Will be deleted when the UnitTest - // object is destructed. By default, a plain text printer is used, - // but the user can set this field to use a custom printer if that - // is desired. - UnitTestEventListenerInterface* result_printer_; + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; // The OS stack trace getter. Will be deleted when the UnitTest // object is destructed. By default, an OsStackTraceGetter is used, @@ -1004,9 +1097,15 @@ class UnitTestImpl { // desired. OsStackTraceGetterInterface* os_stack_trace_getter_; + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + // The random number seed used at the beginning of the test run. int random_seed_; + // Our random number generator. + internal::Random random_; + // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; @@ -1099,13 +1198,14 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. -#if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS && !defined(__GNUC__) + // MSVC and C++ Builder define __int64 instead of the standard long long. typedef unsigned __int64 BiggestConvertible; const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); #else typedef unsigned long long BiggestConvertible; // NOLINT const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); -#endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) const bool parse_success = *end == '\0' && errno == 0; // TODO(vladl@google.com): Convert this to compile time assertion when it is @@ -1131,8 +1231,6 @@ class TestResultAccessor { test_result->RecordProperty(property); } - static bool Passed(const TestResult& result) { return result.Passed(); } - static void ClearTestPartResults(TestResult* test_result) { test_result->ClearTestPartResults(); } diff --git a/gtest/src/gtest-port.cc b/gtest/src/gtest-port.cc index 09d1a8e..de169e2 100644 --- a/gtest/src/gtest-port.cc +++ b/gtest/src/gtest-port.cc @@ -35,14 +35,14 @@ #include <stdlib.h> #include <stdio.h> -#if GTEST_OS_WINDOWS -#ifndef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE +#include <windows.h> // For TerminateProcess() +#elif GTEST_OS_WINDOWS #include <io.h> #include <sys/stat.h> -#endif // _WIN32_WCE #else #include <unistd.h> -#endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_MAC #include <mach/mach_init.h> @@ -50,10 +50,6 @@ #include <mach/vm_map.h> #endif // GTEST_OS_MAC -#ifdef _WIN32_WCE -#include <windows.h> // For TerminateProcess() -#endif // _WIN32_WCE - #include <gtest/gtest-spi.h> #include <gtest/gtest-message.h> #include <gtest/internal/gtest-string.h> @@ -417,20 +413,25 @@ void RE::Init(const char* regex) { #endif // GTEST_USES_POSIX_RE -// Logs a message at the given severity level. -void GTestLog(GTestLogSeverity severity, const char* file, - int line, const char* msg) { + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { const char* const marker = severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; - fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg); - if (severity == GTEST_FATAL) { - fflush(NULL); // abort() is not guaranteed to flush open file streams. + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); posix::Abort(); } } - // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) #ifdef _MSC_VER @@ -444,7 +445,7 @@ class CapturedStderr { public: // The ctor redirects stderr to a temporary file. CapturedStderr() { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Not supported on Windows CE. posix::Abort(); #else @@ -469,24 +470,24 @@ class CapturedStderr { fflush(NULL); dup2(captured_fd, kStdErrFileno); close(captured_fd); -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE } ~CapturedStderr() { -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE remove(filename_.c_str()); -#endif // _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE } // Stops redirecting stderr. void StopCapture() { -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE // Restores the original stream. fflush(NULL); dup2(uncaptured_fd_, kStdErrFileno); close(uncaptured_fd_); uncaptured_fd_ = -1; -#endif // !_WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE } // Returns the name of the temporary file holding the stderr output. @@ -537,7 +538,7 @@ static String ReadEntireFile(FILE * file) { // Starts capturing stderr. void CaptureStderr() { if (g_captured_stderr != NULL) { - GTEST_LOG_(FATAL, "Only one stderr capturer can exist at one time."); + GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time."; } g_captured_stderr = new CapturedStderr; } @@ -568,14 +569,14 @@ const ::std::vector<String>& GetArgvs() { return g_argvs; } #endif // GTEST_HAS_DEATH_TEST -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE namespace posix { void Abort() { DebugBreak(); TerminateProcess(GetCurrentProcess(), 1); } } // namespace posix -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return @@ -585,7 +586,7 @@ static String FlagToEnvVar(const char* flag) { (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; - for (int i = 0; i != full_flag.GetLength(); i++) { + for (size_t i = 0; i != full_flag.length(); i++) { env_var << static_cast<char>(toupper(full_flag.c_str()[i])); } diff --git a/gtest/src/gtest-test-part.cc b/gtest/src/gtest-test-part.cc index f053773..4f36df6 100644 --- a/gtest/src/gtest-test-part.cc +++ b/gtest/src/gtest-test-part.cc @@ -56,12 +56,12 @@ internal::String TestPartResult::ExtractSummary(const char* message) { // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { - return os << result.file_name() << ":" - << result.line_number() << ": " - << (result.type() == TPRT_SUCCESS ? "Success" : - result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" : - "Non-fatal failure") << ":\n" - << result.message() << std::endl; + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; } // Constructs an empty TestPartResultArray. diff --git a/gtest/src/gtest.cc b/gtest/src/gtest.cc index a767d19..9340724 100644 --- a/gtest/src/gtest.cc +++ b/gtest/src/gtest.cc @@ -42,6 +42,8 @@ #include <wchar.h> #include <wctype.h> +#include <ostream> + #if GTEST_OS_LINUX // TODO(kenton@google.com): Use autoconf to detect availability of @@ -70,7 +72,7 @@ // On z/OS we additionally need strings.h for strcasecmp. #include <strings.h> // NOLINT -#elif defined(_WIN32_WCE) // We are on Windows CE. +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. #include <windows.h> // NOLINT @@ -81,7 +83,7 @@ #include <sys/types.h> // NOLINT #include <sys/stat.h> // NOLINT -#if defined(__MINGW__) || defined(__MINGW32__) +#if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). @@ -90,7 +92,7 @@ // supports these. consider using them instead. #define GTEST_HAS_GETTIMEOFDAY_ 1 #include <sys/time.h> // NOLINT -#endif // defined(__MINGW__) || defined(__MINGW32__) +#endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. @@ -129,10 +131,6 @@ namespace testing { -using internal::TestCase; -using internal::TestProperty; -using internal::TestResult; - // Constants. // A test whose test case name or test name matches this filter is @@ -257,6 +255,25 @@ GTEST_DEFINE_bool_( namespace internal { +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. static bool g_help_flag = false; @@ -301,16 +318,22 @@ static bool ShouldRunTestCase(const TestCase* test_case) { } // AssertHelper constructor. -AssertHelper::AssertHelper(TestPartResultType type, const char* file, - int line, const char* message) - : type_(type), file_(file), line_(line), message_(message) { +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; } // Message assignment, for assertion streaming support. void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()-> - AddTestPartResult(type_, file_, line_, - AppendUserMessage(message_, message), + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), UnitTest::GetInstance()->impl() ->CurrentOsStackTraceExceptTop(1) // Skips the stack frame for this function itself. @@ -328,11 +351,11 @@ String g_executable_path; FilePath GetCurrentExecutableName() { FilePath result; -#if defined(_WIN32_WCE) || GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); -#endif // _WIN32_WCE || GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS return result.RemoveDirectoryName(); } @@ -445,7 +468,7 @@ bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter negative = String(""); } else { - positive.Set(p, dash - p); // Everything up to the dash + positive = String(p, dash - p); // Everything up to the dash negative = String(dash+1); // Everything after the dash if (positive.empty()) { // Treat '-test1' as the same as '*-test1' @@ -476,86 +499,6 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { } // namespace internal -// The interface for printing the result of a UnitTest -class UnitTestEventListenerInterface { - public: - // The d'tor is pure virtual as this is an abstract class. - virtual ~UnitTestEventListenerInterface() {} - - // Called before the unit test starts. - virtual void OnUnitTestStart(const UnitTest& unit_test) = 0; - - // Called after the unit test ends. - virtual void OnUnitTestEnd(const UnitTest& unit_test) = 0; - - // Called before the test case starts. - virtual void OnTestCaseStart(const TestCase& test_case) = 0; - - // Called after the test case ends. - virtual void OnTestCaseEnd(const TestCase& test_case) = 0; - - // Called before the global set-up starts. - virtual void OnGlobalSetUpStart(const UnitTest& unit_test) = 0; - - // Called after the global set-up ends. - virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) = 0; - - // Called before the global tear-down starts. - virtual void OnGlobalTearDownStart(const UnitTest& unit_test) = 0; - - // Called after the global tear-down ends. - virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) = 0; - - // Called before the test starts. - virtual void OnTestStart(const TestInfo& test_info) = 0; - - // Called after the test ends. - virtual void OnTestEnd(const TestInfo& test_info) = 0; - - // Called after an assertion. - virtual void OnNewTestPartResult(const TestPartResult& test_part_result) = 0; -}; - -// The convenience class for users who need to override just one or two -// methods and are not concerned that a possible change to a signature of -// the methods they override will not be caught during the build. -class EmptyTestEventListener : public UnitTestEventListenerInterface { - public: - // Called before the unit test starts. - virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {} - - // Called after the unit test ends. - virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) {} - - // Called before the test case starts. - virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} - - // Called after the test case ends. - virtual void OnTestCaseEnd(const TestCase& /*test_case&*/) {} - - // Called before the global set-up starts. - virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) {} - - // Called after the global set-up ends. - virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {} - - // Called before the global tear-down starts. - virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) {} - - // Called after the global tear-down ends. - virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {} - - // Called before the test starts. - virtual void OnTestStart(const TestInfo& /*test_info*/) {} - - // Called after the test ends. - virtual void OnTestEnd(const TestInfo& /*test_info*/) {} - - // Called after an assertion. - virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) { - } -}; - // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. Intercepts only failures from the current thread. @@ -631,11 +574,11 @@ AssertionResult HasOneFailure(const char* /* results_expr */, const char* /* type_expr */, const char* /* substr_expr */, const TestPartResultArray& results, - TestPartResultType type, + TestPartResult::Type type, const char* substr) { - const String expected( - type == TPRT_FATAL_FAILURE ? "1 fatal failure" : - "1 non-fatal failure"); + const String expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); Message msg; if (results.size() != 1) { msg << "Expected: " << expected << "\n" @@ -670,7 +613,7 @@ AssertionResult HasOneFailure(const char* /* results_expr */, // substring the failure message should contain. SingleFailureChecker:: SingleFailureChecker( const TestPartResultArray* results, - TestPartResultType type, + TestPartResult::Type type, const char* substr) : results_(results), type_(type), @@ -690,7 +633,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( void DefaultGlobalTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->current_test_result()->AddTestPartResult(result); - unit_test_->result_printer()->OnNewTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( @@ -790,7 +733,7 @@ String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { // Returns the current time in milliseconds. TimeInMillis GetTimeInMillis() { -#if defined(_WIN32_WCE) || defined(__BORLANDC__) +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) // Difference between 1970-01-01 and 1601-01-01 in milliseconds. // http://analogous.blogspot.com/2005/04/epoch.html const TimeInMillis kJavaEpochToWinFileTimeDelta = @@ -873,7 +816,7 @@ const char * String::CloneCString(const char* c_str) { NULL : CloneString(c_str, strlen(c_str)); } -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the @@ -907,7 +850,7 @@ const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { return ansi; } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE // Compares two C strings. Returns true iff they have the same content. // @@ -926,17 +869,17 @@ bool String::CStringEquals(const char * lhs, const char * rhs) { // Converts an array of wide chars to a narrow string using the UTF-8 // encoding, and streams the result to the given Message object. -static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len, +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, Message* msg) { // TODO(wan): consider allowing a testing::String object to // contain '\0'. This will make it behave more like std::string, // and will allow ToUtf8String() to return the correct encoding // for '\0' s.t. we can get rid of the conditional here (and in // several other places). - for (size_t i = 0; i != len; ) { // NOLINT + for (size_t i = 0; i != length; ) { // NOLINT if (wstr[i] != L'\0') { - *msg << WideStringToUtf8(wstr + i, static_cast<int>(len - i)); - while (i != len && wstr[i] != L'\0') + *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i)); + while (i != length && wstr[i] != L'\0') i++; } else { *msg << '\0'; @@ -1381,7 +1324,7 @@ namespace { AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't support FormatMessage. const char error_text[] = ""; #else @@ -1405,7 +1348,7 @@ AssertionResult HRESULTFailureHelper(const char* expr, --message_length) { error_text[message_length - 1] = '\0'; } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE const String error_hex(String::Format("0x%08X ", hr)); Message msg; @@ -1679,24 +1622,30 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, #endif // OS selector } -// Constructs a String by copying a given number of chars from a -// buffer. E.g. String("hello", 3) will create the string "hel". -String::String(const char * buffer, size_t len) { - char * const temp = new char[ len + 1 ]; - memcpy(temp, buffer, len); - temp[ len ] = '\0'; - c_str_ = temp; -} - // Compares this with another String. // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 // if this is greater than rhs. int String::Compare(const String & rhs) const { - if ( c_str_ == NULL ) { - return rhs.c_str_ == NULL ? 0 : -1; // NULL < anything except NULL + const char* const lhs_c_str = c_str(); + const char* const rhs_c_str = rhs.c_str(); + + if (lhs_c_str == NULL) { + return rhs_c_str == NULL ? 0 : -1; // NULL < anything except NULL + } else if (rhs_c_str == NULL) { + return 1; } - return rhs.c_str_ == NULL ? 1 : strcmp(c_str_, rhs.c_str_); + const size_t shorter_str_len = + length() <= rhs.length() ? length() : rhs.length(); + for (size_t i = 0; i != shorter_str_len; i++) { + if (lhs_c_str[i] < rhs_c_str[i]) { + return -1; + } else if (lhs_c_str[i] > rhs_c_str[i]) { + return 1; + } + } + return (length() < rhs.length()) ? -1 : + (length() > rhs.length()) ? 1 : 0; } // Returns true iff this String ends with the given suffix. *Any* @@ -1704,12 +1653,12 @@ int String::Compare(const String & rhs) const { bool String::EndsWith(const char* suffix) const { if (suffix == NULL || CStringEquals(suffix, "")) return true; - if (c_str_ == NULL) return false; + if (c_str() == NULL) return false; - const size_t this_len = strlen(c_str_); + const size_t this_len = strlen(c_str()); const size_t suffix_len = strlen(suffix); return (this_len >= suffix_len) && - CStringEquals(c_str_ + this_len - suffix_len, suffix); + CStringEquals(c_str() + this_len - suffix_len, suffix); } // Returns true iff this String ends with the given suffix, ignoring case. @@ -1717,37 +1666,12 @@ bool String::EndsWith(const char* suffix) const { bool String::EndsWithCaseInsensitive(const char* suffix) const { if (suffix == NULL || CStringEquals(suffix, "")) return true; - if (c_str_ == NULL) return false; + if (c_str() == NULL) return false; - const size_t this_len = strlen(c_str_); + const size_t this_len = strlen(c_str()); const size_t suffix_len = strlen(suffix); return (this_len >= suffix_len) && - CaseInsensitiveCStringEquals(c_str_ + this_len - suffix_len, suffix); -} - -// Sets the 0-terminated C string this String object represents. The -// old string in this object is deleted, and this object will own a -// clone of the input string. This function copies only up to length -// bytes (plus a terminating null byte), or until the first null byte, -// whichever comes first. -// -// This function works even when the c_str parameter has the same -// value as that of the c_str_ field. -void String::Set(const char * c_str, size_t length) { - // Makes sure this works when c_str == c_str_ - const char* const temp = CloneString(c_str, length); - delete[] c_str_; - c_str_ = temp; -} - -// Assigns a C string to this object. Self-assignment works. -const String& String::operator=(const char* c_str) { - // Makes sure this works when c_str == c_str_ - if (c_str != c_str_) { - delete[] c_str_; - c_str_ = CloneCString(c_str); - } - return *this; + CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix); } // Formats a list of arguments to a String, using the same format @@ -1757,28 +1681,38 @@ const String& String::operator=(const char* c_str) { // available. // // The result is limited to 4096 characters (including the tailing 0). -// If 4096 characters are not enough to format the input, -// "<buffer exceeded>" is returned. +// If 4096 characters are not enough to format the input, or if +// there's an error, "<formatting error or buffer exceeded>" is +// returned. String String::Format(const char * format, ...) { va_list args; va_start(args, format); char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning // 4996 (deprecated function) there. #ifdef _MSC_VER // We are using MSVC. #pragma warning(push) // Saves the current warning state. #pragma warning(disable:4996) // Temporarily disables warning 4996. - const int size = - vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); + const int size = vsnprintf(buffer, kBufferSize, format, args); #pragma warning(pop) // Restores the warning state. #else // We are not using MSVC. - const int size = - vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); + const int size = vsnprintf(buffer, kBufferSize, format, args); #endif // _MSC_VER va_end(args); - return String(size >= 0 ? buffer : "<buffer exceeded>"); + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return String("<formatting error or buffer exceeded>"); + } else { + return String(buffer, size); + } } // Converts the buffer in a StrStream to a String, converting NUL @@ -1829,6 +1763,8 @@ String AppendUserMessage(const String& gtest_msg, return msg.GetString(); } +} // namespace internal + // class TestResult // Creates an empty TestResult. @@ -1948,8 +1884,6 @@ int TestResult::test_property_count() const { return test_properties_->size(); } -} // namespace internal - // class Test // Creates a Test object. @@ -1990,7 +1924,7 @@ void Test::RecordProperty(const char* key, int value) { namespace internal { -void ReportFailureInUnknownLocation(TestPartResultType result_type, +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const String& message) { // This function is a friend of UnitTest and as such has access to // AddTestPartResult. @@ -2014,7 +1948,7 @@ static void AddExceptionThrownFailure(DWORD exception_code, message << "Exception thrown with code 0x" << std::setbase(16) << exception_code << std::setbase(10) << " in " << location << "."; - internal::ReportFailureInUnknownLocation(TPRT_FATAL_FAILURE, + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, message.GetString()); } @@ -2316,11 +2250,10 @@ void TestInfoImpl::Run() { UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_info(parent_); - // Notifies the unit test event listener that a test is about to - // start. - UnitTestEventListenerInterface* const result_printer = - impl->result_printer(); - result_printer->OnTestStart(*parent_); + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*parent_); const TimeInMillis start = GetTimeInMillis(); @@ -2363,13 +2296,15 @@ void TestInfoImpl::Run() { result_.set_elapsed_time(GetTimeInMillis() - start); // Notifies the unit test event listener that a test has just finished. - result_printer->OnTestEnd(*parent_); + repeater->OnTestEnd(*parent_); // Tells UnitTest to stop associating assertion results to this // test. impl->set_current_test_info(NULL); } +} // namespace internal + // class TestCase // Gets the number of successful tests in this test case. @@ -2408,33 +2343,39 @@ TestCase::TestCase(const char* name, const char* comment, Test::TearDownTestCaseFunc tear_down_tc) : name_(name), comment_(comment), + test_info_list_(new internal::Vector<TestInfo*>), + test_indices_(new internal::Vector<int>), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), elapsed_time_(0) { - test_info_list_ = new internal::Vector<TestInfo *>; } // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. test_info_list_->ForEach(internal::Delete<TestInfo>); - - // Then deletes the Test collection. - delete test_info_list_; - test_info_list_ = NULL; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* TestCase::GetTestInfo(int i) const { - return test_info_list_->GetElementOr(i, NULL); + const int index = test_indices_->GetElementOr(i, -1); + return index < 0 ? NULL : test_info_list_->GetElement(index); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = test_indices_->GetElementOr(i, -1); + return index < 0 ? NULL : test_info_list_->GetElement(index); } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. void TestCase::AddTestInfo(TestInfo * test_info) { test_info_list_->PushBack(test_info); + test_indices_->PushBack(test_indices_->size()); } // Runs every test in this TestCase. @@ -2444,20 +2385,21 @@ void TestCase::Run() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_case(this); - UnitTestEventListenerInterface * const result_printer = - impl->result_printer(); + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - result_printer->OnTestCaseStart(*this); + repeater->OnTestCaseStart(*this); impl->os_stack_trace_getter()->UponLeavingGTest(); set_up_tc_(); const internal::TimeInMillis start = internal::GetTimeInMillis(); - test_info_list_->ForEach(internal::TestInfoImpl::RunTest); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->impl()->Run(); + } elapsed_time_ = internal::GetTimeInMillis() - start; impl->os_stack_trace_getter()->UponLeavingGTest(); tear_down_tc_(); - result_printer->OnTestCaseEnd(*this); + repeater->OnTestCaseEnd(*this); impl->set_current_test_case(NULL); } @@ -2488,11 +2430,17 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) { return test_info->impl()->should_run(); } -} // namespace internal +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + test_indices_->Shuffle(random); +} -// A result printer that never prints anything. Used in the child process -// of an exec-style death test to avoid needless output clutter. -class NullUnitTestResultPrinter : public EmptyTestEventListener {}; +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (int i = 0; i < test_indices_->size(); i++) { + test_indices_->GetMutableElement(i) = i; + } +} // Formats a countable noun. Depending on its quantity, either the // singular form or the plural form is used. e.g. @@ -2516,17 +2464,17 @@ static internal::String FormatTestCaseCount(int test_case_count) { return FormatCountableNoun(test_case_count, "test case", "test cases"); } -// Converts a TestPartResultType enum to human-friendly string -// representation. Both TPRT_NONFATAL_FAILURE and TPRT_FATAL_FAILURE -// are translated to "Failure", as the user usually doesn't care about -// the difference between the two when viewing the test result. -static const char * TestPartResultTypeToString(TestPartResultType type) { +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { switch (type) { - case TPRT_SUCCESS: + case TestPartResult::kSuccess: return "Success"; - case TPRT_NONFATAL_FAILURE: - case TPRT_FATAL_FAILURE: + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: #ifdef _MSC_VER return "error: "; #else @@ -2557,12 +2505,10 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) { // following statements add the test part result message to the Output // window such that the user can double-click on it to jump to the // corresponding source code location; otherwise they do nothing. -#ifdef _WIN32_WCE - // Windows Mobile doesn't support the ANSI version of OutputDebugString, - // it works only with UTF16 strings. - ::OutputDebugString(internal::String::AnsiToUtf16(result.c_str())); - ::OutputDebugString(L"\n"); -#elif GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. ::OutputDebugStringA(result.c_str()); ::OutputDebugStringA("\n"); #endif @@ -2579,7 +2525,7 @@ enum GTestColor { COLOR_YELLOW }; -#if GTEST_OS_WINDOWS && !defined(_WIN32_WCE) +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { @@ -2604,7 +2550,7 @@ const char* GetAnsiColorCode(GTestColor color) { }; } -#endif // GTEST_OS_WINDOWS && !_WIN32_WCE +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns true iff Google Test should use colors in the output. bool ShouldUseColor(bool stdout_is_tty) { @@ -2645,13 +2591,13 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); -#if defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS const bool use_color = false; #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); const bool use_color = in_color_mode && (color != COLOR_DEFAULT); -#endif // defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS // The '!= 0' comparison is necessary to satisfy MSVC 7.1. if (!use_color) { @@ -2660,7 +2606,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if GTEST_OS_WINDOWS && !defined(_WIN32_WCE) +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -2678,41 +2624,34 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. -#endif // GTEST_OS_WINDOWS && !defined(_WIN32_WCE) +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE va_end(args); } -} // namespace internal - -using internal::ColoredPrintf; -using internal::COLOR_DEFAULT; -using internal::COLOR_RED; -using internal::COLOR_GREEN; -using internal::COLOR_YELLOW; - -// This class implements the UnitTestEventListenerInterface interface. +// This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. -class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface { +class PrettyUnitTestResultPrinter : public TestEventListener { public: PrettyUnitTestResultPrinter() {} static void PrintTestName(const char * test_case, const char * test) { printf("%s.%s", test_case, test); } - // The following methods override what's in the - // UnitTestEventListenerInterface class. - virtual void OnUnitTestStart(const UnitTest& unit_test); - virtual void OnGlobalSetUpStart(const UnitTest& unit_test); - virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {} + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& test_case); - virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); - virtual void OnNewTestPartResult(const TestPartResult& result); + virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); - virtual void OnGlobalTearDownStart(const UnitTest& unit_test); - virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {} - virtual void OnUnitTestEnd(const UnitTest& unit_test); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} private: static void PrintFailedTests(const UnitTest& unit_test); @@ -2720,8 +2659,12 @@ class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface { internal::String test_case_name_; }; -// Called before the unit test starts. -void PrettyUnitTestResultPrinter::OnUnitTestStart(const UnitTest& unit_test) { + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + const char* const filter = GTEST_FLAG(filter).c_str(); // Prints the filter if it's not *. This reminds the user that some @@ -2751,7 +2694,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(const UnitTest& unit_test) { fflush(stdout); } -void PrettyUnitTestResultPrinter::OnGlobalSetUpStart( +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment set-up.\n"); @@ -2772,19 +2715,6 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { - if (!GTEST_FLAG(print_time)) return; - - test_case_name_ = test_case.name(); - const internal::String counts = - FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("%s from %s (%s ms total)\n\n", - counts.c_str(), test_case_name_.c_str(), - internal::StreamableToString(test_case.elapsed_time()).c_str()); - fflush(stdout); -} - void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { ColoredPrintf(COLOR_GREEN, "[ RUN ] "); PrintTestName(test_case_name_.c_str(), test_info.name()); @@ -2796,6 +2726,18 @@ void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { fflush(stdout); } +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { if (test_info.result()->Passed()) { ColoredPrintf(COLOR_GREEN, "[ OK ] "); @@ -2812,19 +2754,20 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { fflush(stdout); } -// Called after an assertion failure. -void PrettyUnitTestResultPrinter::OnNewTestPartResult( - const TestPartResult& result) { - // If the test part succeeded, we don't need to do anything. - if (result.type() == TPRT_SUCCESS) - return; +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; - // Print failure message from the assertion (e.g. expected this and got that). - PrintTestPartResult(result); + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case_name_.c_str(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); } -void PrettyUnitTestResultPrinter::OnGlobalTearDownStart( +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment tear-down\n"); @@ -2863,7 +2806,8 @@ void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { } } -void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) { + void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { ColoredPrintf(COLOR_GREEN, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), @@ -2902,76 +2846,129 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) { // End PrettyUnitTestResultPrinter -// class UnitTestEventsRepeater +// class TestEventRepeater // // This class forwards events to other event listeners. -class UnitTestEventsRepeater : public UnitTestEventListenerInterface { +class TestEventRepeater : public TestEventListener { public: - typedef internal::Vector<UnitTestEventListenerInterface *> Listeners; - UnitTestEventsRepeater() {} - virtual ~UnitTestEventsRepeater(); - void AddListener(UnitTestEventListenerInterface *listener); - - virtual void OnUnitTestStart(const UnitTest& unit_test); - virtual void OnUnitTestEnd(const UnitTest& unit_test); - virtual void OnGlobalSetUpStart(const UnitTest& unit_test); - virtual void OnGlobalSetUpEnd(const UnitTest& unit_test); - virtual void OnGlobalTearDownStart(const UnitTest& unit_test); - virtual void OnGlobalTearDownEnd(const UnitTest& unit_test); + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); virtual void OnTestCaseStart(const TestCase& test_case); - virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); - virtual void OnNewTestPartResult(const TestPartResult& result); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); private: - Listeners listeners_; + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + Vector<TestEventListener*> listeners_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestEventsRepeater); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; -UnitTestEventsRepeater::~UnitTestEventsRepeater() { +TestEventRepeater::~TestEventRepeater() { for (int i = 0; i < listeners_.size(); i++) { delete listeners_.GetElement(i); } } -void UnitTestEventsRepeater::AddListener( - UnitTestEventListenerInterface *listener) { +void TestEventRepeater::Append(TestEventListener *listener) { listeners_.PushBack(listener); } -// Since the methods are identical, use a macro to reduce boilerplate. -// This defines a member that repeats the call to all listeners. +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (int i = 0; i < listeners_.size(); ++i) { + if (listeners_.GetElement(i) == listener) { + listeners_.Erase(i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. #define GTEST_REPEATER_METHOD_(Name, Type) \ -void UnitTestEventsRepeater::Name(const Type& parameter) { \ - for (int i = 0; i < listeners_.size(); i++) { \ - listeners_.GetElement(i)->Name(parameter); \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = 0; i < listeners_.size(); i++) { \ + listeners_.GetElement(i)->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_.GetElement(i)->Name(parameter); \ + } \ } \ } -GTEST_REPEATER_METHOD_(OnUnitTestStart, UnitTest) -GTEST_REPEATER_METHOD_(OnUnitTestEnd, UnitTest) -GTEST_REPEATER_METHOD_(OnGlobalSetUpStart, UnitTest) -GTEST_REPEATER_METHOD_(OnGlobalSetUpEnd, UnitTest) -GTEST_REPEATER_METHOD_(OnGlobalTearDownStart, UnitTest) -GTEST_REPEATER_METHOD_(OnGlobalTearDownEnd, UnitTest) +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) -GTEST_REPEATER_METHOD_(OnTestCaseEnd, TestCase) GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) -GTEST_REPEATER_METHOD_(OnTestEnd, TestInfo) -GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) #undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ -// End PrettyUnitTestResultPrinter +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = 0; i < listeners_.size(); i++) { + listeners_.GetElement(i)->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { + listeners_.GetElement(i)->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater // This class generates an XML output file. class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: explicit XmlUnitTestResultPrinter(const char* output_file); - virtual void OnUnitTestEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); private: // Is c a whitespace character that is normalized to a space character @@ -2989,23 +2986,26 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { // is_attribute is true, the text is meant to appear as an attribute // value, and normalizable whitespace is preserved by replacing it // with character references. - static internal::String EscapeXml(const char* str, - bool is_attribute); + static String EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static String RemoveInvalidXmlCharacters(const char* str); // Convenience wrapper around EscapeXml when str is an attribute value. - static internal::String EscapeXmlAttribute(const char* str) { + static String EscapeXmlAttribute(const char* str) { return EscapeXml(str, true); } // Convenience wrapper around EscapeXml when str is not an attribute value. - static internal::String EscapeXmlText(const char* str) { - return EscapeXml(str, false); - } + static String EscapeXmlText(const char* str) { return EscapeXml(str, false); } - // Prints an XML representation of a TestInfo object. - static void PrintXmlTestInfo(FILE* out, - const char* test_case_name, - const TestInfo& test_info); + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); // Prints an XML representation of a TestCase object static void PrintXmlTestCase(FILE* out, const TestCase& test_case); @@ -3017,11 +3017,10 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { // delimited XML attributes based on the property key="value" pairs. // When the String is not empty, it includes a space at the beginning, // to delimit this attribute from prior attributes. - static internal::String TestPropertiesAsXmlAttributes( - const TestResult& result); + static String TestPropertiesAsXmlAttributes(const TestResult& result); // The output file. - const internal::String output_file_; + const String output_file_; GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; @@ -3037,13 +3036,14 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) } // Called after the unit test ends. -void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) { +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { FILE* xmlout = NULL; - internal::FilePath output_file(output_file_); - internal::FilePath output_dir(output_file.RemoveFileName()); + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); if (output_dir.CreateDirectoriesRecursively()) { - xmlout = internal::posix::FOpen(output_file_.c_str(), "w"); + xmlout = posix::FOpen(output_file_.c_str(), "w"); } if (xmlout == NULL) { // TODO(wan): report the reason of the failure. @@ -3078,8 +3078,7 @@ void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) { // most invalid characters can be retained using character references. // TODO(wan): It might be nice to have a minimally invasive, human-readable // escaping scheme for invalid characters, rather than dropping them. -internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, - bool is_attribute) { +String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { Message m; if (str != NULL) { @@ -3109,7 +3108,7 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, default: if (IsValidXmlCharacter(*src)) { if (is_attribute && IsNormalizableWhitespace(*src)) - m << internal::String::Format("&#x%02X;", unsigned(*src)); + m << String::Format("&#x%02X;", unsigned(*src)); else m << *src; } @@ -3121,6 +3120,21 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, return m.GetString(); } +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { + char* const output = new char[strlen(str) + 1]; + char* appender = output; + for (char ch = *str; ch != '\0'; ch = *++str) + if (IsValidXmlCharacter(ch)) + *appender++ = ch; + *appender = '\0'; + + String ret_value(output); + delete[] output; + return ret_value; +} // The following routines generate an XML representation of a UnitTest // object. @@ -3138,8 +3152,6 @@ internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, // </testsuite> // </testsuites> -namespace internal { - // Formats the given time in milliseconds as seconds. The returned // C-string is owned by this function and cannot be released by the // caller. Calling the function again invalidates the previous @@ -3150,43 +3162,62 @@ const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) { return str.c_str(); } -} // namespace internal +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << "<![CDATA["; + for (;;) { + const char* const next_segment = strstr(segment, "]]>"); + if (next_segment != NULL) { + stream->write(segment, next_segment - segment); + *stream << "]]>]]><![CDATA["; + segment = next_segment + strlen("]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} // Prints an XML representation of a TestInfo object. // TODO(wan): There is also value in printing properties with the plain printer. -void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out, - const char* test_case_name, - const TestInfo& test_info) { +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { const TestResult& result = *test_info.result(); - fprintf(out, - " <testcase name=\"%s\" status=\"%s\" time=\"%s\" " - "classname=\"%s\"%s", - EscapeXmlAttribute(test_info.name()).c_str(), - test_info.should_run() ? "run" : "notrun", - internal::FormatTimeInMillisAsSeconds(result.elapsed_time()), - EscapeXmlAttribute(test_case_name).c_str(), - TestPropertiesAsXmlAttributes(result).c_str()); + *stream << " <testcase name=\"" + << EscapeXmlAttribute(test_info.name()).c_str() + << "\" status=\"" + << (test_info.should_run() ? "run" : "notrun") + << "\" time=\"" + << FormatTimeInMillisAsSeconds(result.elapsed_time()) + << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str() + << "\"" << TestPropertiesAsXmlAttributes(result).c_str(); int failures = 0; for (int i = 0; i < result.total_part_count(); ++i) { const TestPartResult& part = result.GetTestPartResult(i); if (part.failed()) { - const internal::String message = - internal::String::Format("%s:%d\n%s", part.file_name(), - part.line_number(), part.message()); if (++failures == 1) - fprintf(out, ">\n"); - fprintf(out, - " <failure message=\"%s\" type=\"\"><![CDATA[%s]]>" - "</failure>\n", - EscapeXmlAttribute(part.summary()).c_str(), message.c_str()); + *stream << ">\n"; + *stream << " <failure message=\"" + << EscapeXmlAttribute(part.summary()).c_str() + << "\" type=\"\">"; + const String message = RemoveInvalidXmlCharacters(String::Format( + "%s:%d\n%s", + part.file_name(), part.line_number(), + part.message()).c_str()); + OutputXmlCDataSection(stream, message.c_str()); + *stream << "</failure>\n"; } } if (failures == 0) - fprintf(out, " />\n"); + *stream << " />\n"; else - fprintf(out, " </testcase>\n"); + *stream << " </testcase>\n"; } // Prints an XML representation of a TestCase object @@ -3201,9 +3232,12 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, test_case.disabled_test_count()); fprintf(out, "errors=\"0\" time=\"%s\">\n", - internal::FormatTimeInMillisAsSeconds(test_case.elapsed_time())); - for (int i = 0; i < test_case.total_test_count(); ++i) - PrintXmlTestInfo(out, test_case.name(), *test_case.GetTestInfo(i)); + FormatTimeInMillisAsSeconds(test_case.elapsed_time())); + for (int i = 0; i < test_case.total_test_count(); ++i) { + StrStream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StrStreamToString(&stream).c_str()); + } fprintf(out, " </testsuite>\n"); } @@ -3217,7 +3251,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, unit_test.total_test_count(), unit_test.failed_test_count(), unit_test.disabled_test_count(), - internal::FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); if (GTEST_FLAG(shuffle)) { fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed()); } @@ -3229,7 +3263,7 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. -internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( +String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( const TestResult& result) { Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { @@ -3242,8 +3276,6 @@ internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( // End XmlUnitTestResultPrinter -namespace internal { - // Class ScopedTrace // Pushes the given source file location and message onto a per-thread @@ -3290,6 +3322,81 @@ OsStackTraceGetter::kElidedFramesMarker = } // namespace internal +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + // class UnitTest // Gets the singleton UnitTest object. The first time this method is @@ -3378,6 +3485,18 @@ const TestCase* UnitTest::GetTestCase(int i) const { return impl()->GetTestCase(i); } +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in the // order they were registered. After all tests in the program have @@ -3416,7 +3535,7 @@ class GoogleTestFailureException : public ::std::runtime_error { // this to report their results. The user code should use the // assertion macros instead of calling this directly. // L < mutex_ -void UnitTest::AddTestPartResult(TestPartResultType result_type, +void UnitTest::AddTestPartResult(TestPartResult::Type result_type, const char* file_name, int line_number, const internal::String& message, @@ -3446,7 +3565,7 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, impl_->GetTestPartResultReporterForCurrentThread()-> ReportTestPartResult(result); - if (result_type != TPRT_SUCCESS) { + if (result_type != TestPartResult::kSuccess) { // gtest_break_on_failure takes precedence over // gtest_throw_on_failure. This allows a user to set the latter // in the code (perhaps in order to use Google Test assertions @@ -3491,27 +3610,27 @@ int UnitTest::Run() { // Catch SEH-style exceptions. const bool in_death_test_child_process = - internal::GTEST_FLAG(internal_run_death_test).GetLength() > 0; + internal::GTEST_FLAG(internal_run_death_test).length() > 0; // Either the user wants Google Test to catch exceptions thrown by the // tests or this is executing in the context of death test child // process. In either case the user does not want to see pop-up dialogs // about crashes - they are expected.. if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { -#if !defined(_WIN32_WCE) +#if !GTEST_OS_WINDOWS_MOBILE // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); -#endif // _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE -#if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(_WIN32_WCE) +#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); #endif -#if _MSC_VER >= 1400 && !defined(_WIN32_WCE) +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement @@ -3624,7 +3743,6 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), - test_cases_(), #if GTEST_HAS_PARAM_TEST parameterized_test_registry_(), parameterized_tests_registered_(false), @@ -3633,9 +3751,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) current_test_case_(NULL), current_test_info_(NULL), ad_hoc_test_result_(), - result_printer_(NULL), os_stack_trace_getter_(NULL), - random_seed_(0), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. #if GTEST_HAS_DEATH_TEST elapsed_time_(0), internal_run_death_test_flag_(NULL), @@ -3643,6 +3762,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) #else elapsed_time_(0) { #endif // GTEST_HAS_DEATH_TEST + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } UnitTestImpl::~UnitTestImpl() { @@ -3652,12 +3772,58 @@ UnitTestImpl::~UnitTestImpl() { // Deletes every Environment. environments_.ForEach(internal::Delete<Environment>); - // Deletes the current test result printer. - delete result_printer_; - delete os_stack_trace_getter_; } +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const String& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + } +} + // A predicate that checks the name of a TestCase against a known // value. // @@ -3682,7 +3848,9 @@ class TestCaseNameIs { }; // Finds and returns a TestCase with the given name. If one doesn't -// exist, creates one and returns it. +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. // // Arguments: // @@ -3707,13 +3875,16 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), kDeathTestCaseFilter)) { // Yes. Inserts the test case after the last death test case - // defined so far. + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. test_cases_.Insert(new_test_case, ++last_death_test_case_); } else { // No. Appends to the end of the list. test_cases_.PushBack(new_test_case); } + test_case_indices_.PushBack(test_case_indices_.size()); return new_test_case; } @@ -3728,7 +3899,7 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); } // considered to be failed, but the rest of the tests will still be // run. (We disable exceptions on Linux and Mac OS X, so the issue // doesn't apply there.) -// When parameterized tests are enabled, it explands and registers +// When parameterized tests are enabled, it expands and registers // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. @@ -3745,7 +3916,9 @@ int UnitTestImpl::RunAllTests() { if (g_help_flag) return 0; - RegisterParameterizedTests(); + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding @@ -3757,12 +3930,9 @@ int UnitTestImpl::RunAllTests() { bool in_subprocess_for_death_test = false; #if GTEST_HAS_DEATH_TEST - internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST - UnitTestEventListenerInterface * const printer = result_printer(); - const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, in_subprocess_for_death_test); @@ -3785,59 +3955,79 @@ int UnitTestImpl::RunAllTests() { // True iff at least one test has failed. bool failed = false; + TestEventListener* repeater = listeners()->repeater(); + + repeater->OnTestProgramStart(*parent_); + // How many times to repeat the tests? We don't want to repeat them // when we are inside the subprocess of a death test. const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); // Repeats forever if the repeat count is negative. const bool forever = repeat < 0; for (int i = 0; forever || i != repeat; i++) { - if (repeat != 1) { - printf("\nRepeating all tests (iteration %d) . . .\n\n", i + 1); - } - - // Tells the unit test event listener that the tests are about to - // start. - printer->OnUnitTestStart(*parent_); + ClearResult(); const TimeInMillis start = GetTimeInMillis(); + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + // Runs each test case if there is at least one test to run. if (has_tests_to_run) { // Sets up all environments beforehand. - printer->OnGlobalSetUpStart(*parent_); + repeater->OnEnvironmentsSetUpStart(*parent_); environments_.ForEach(SetUpEnvironment); - printer->OnGlobalSetUpEnd(*parent_); + repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { - test_cases_.ForEach(TestCase::RunTestCase); + for (int i = 0; i < total_test_case_count(); i++) { + GetMutableTestCase(i)->Run(); + } } // Tears down all environments in reverse order afterwards. - printer->OnGlobalTearDownStart(*parent_); + repeater->OnEnvironmentsTearDownStart(*parent_); environments_in_reverse_order_.ForEach(TearDownEnvironment); - printer->OnGlobalTearDownEnd(*parent_); + repeater->OnEnvironmentsTearDownEnd(*parent_); } elapsed_time_ = GetTimeInMillis() - start; - // Tells the unit test event listener that the tests have just - // finished. - printer->OnUnitTestEnd(*parent_); + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); // Gets the result and clears it. if (!Passed()) { failed = true; } - ClearResult(); + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); if (GTEST_FLAG(shuffle)) { - // Picks a new random seed for each run. + // Picks a new random seed for each iteration. random_seed_ = GetNextRandomSeed(random_seed_); } } + repeater->OnTestProgramEnd(*parent_); + // Returns 0 if all tests passed, or 1 other wise. return failed ? 1 : 0; } @@ -4016,49 +4206,6 @@ void UnitTestImpl::ListTestsMatchingFilter() { fflush(stdout); } -// Sets the unit test result printer. -// -// Does nothing if the input and the current printer object are the -// same; otherwise, deletes the old printer object and makes the -// input the current printer. -void UnitTestImpl::set_result_printer( - UnitTestEventListenerInterface* result_printer) { - if (result_printer_ != result_printer) { - delete result_printer_; - result_printer_ = result_printer; - } -} - -// Returns the current unit test result printer if it is not NULL; -// otherwise, creates an appropriate result printer, makes it the -// current printer, and returns it. -UnitTestEventListenerInterface* UnitTestImpl::result_printer() { - if (result_printer_ != NULL) { - return result_printer_; - } - -#if GTEST_HAS_DEATH_TEST - if (internal_run_death_test_flag_.get() != NULL) { - result_printer_ = new NullUnitTestResultPrinter; - return result_printer_; - } -#endif // GTEST_HAS_DEATH_TEST - - UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater; - const String& output_format = internal::UnitTestOptions::GetOutputFormat(); - if (output_format == "xml") { - repeater->AddListener(new XmlUnitTestResultPrinter( - internal::UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); - } else if (output_format != "") { - printf("WARNING: unrecognized output format \"%s\" ignored.\n", - output_format.c_str()); - fflush(stdout); - } - repeater->AddListener(new PrettyUnitTestResultPrinter); - result_printer_ = repeater; - return result_printer_; -} - // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter are @@ -4090,6 +4237,32 @@ TestResult* UnitTestImpl::current_test_result() { current_test_info_->impl()->result() : &ad_hoc_test_result_; } +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + test_case_indices_.ShuffleRange(random(), 0, last_death_test_case_ + 1); + + // Shuffles the non-death test cases. + test_case_indices_.ShuffleRange(random(), last_death_test_case_ + 1, + test_cases_.size()); + + // Shuffles the tests inside each test case. + for (int i = 0; i < test_cases_.size(); i++) { + test_cases_.GetElement(i)->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (int i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_.GetElement(i)->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_.GetMutableElement(i) = i; + } +} + // TestInfoImpl constructor. The new instance assumes ownership of the test // factory object. TestInfoImpl::TestInfoImpl(TestInfo* parent, @@ -4126,7 +4299,8 @@ TestInfoImpl::~TestInfoImpl() { // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count) { +String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); @@ -4138,11 +4312,13 @@ namespace { class ClassUniqueToAlwaysTrue {}; } +bool IsTrue(bool condition) { return condition; } + bool AlwaysTrue() { #if GTEST_HAS_EXCEPTIONS // This condition is always false so AlwaysTrue() never actually throws, // but it makes the compiler think that it may throw. - if (atoi("42") == 36) // NOLINT + if (IsTrue(false)) throw ClassUniqueToAlwaysTrue(); #endif // GTEST_HAS_EXCEPTIONS return true; @@ -4161,7 +4337,7 @@ const char* ParseFlagValue(const char* str, // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag); - const size_t flag_len = flag_str.GetLength(); + const size_t flag_len = flag_str.length(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; // Skips the flag name. @@ -4301,8 +4477,8 @@ static const char kColorEncodedHelpMessage[] = "Test Execution:\n" " @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" " Run the tests repeatedly; use a negative count to repeat forever.\n" -" @G--" GTEST_FLAG_PREFIX_ "shuffle\n" -" Randomize tests' orders on every run. To be implemented.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" " @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" " Random number seed to use for shuffling test orders (between 1 and\n" " 99999, or 0 to use a seed based on the current time).\n" @@ -4439,6 +4615,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { #endif // GTEST_HAS_DEATH_TEST ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); } } // namespace internal diff --git a/gtest/test/gtest-death-test_test.cc b/gtest/test/gtest-death-test_test.cc index 1881139..288c70a 100644 --- a/gtest/test/gtest-death-test_test.cc +++ b/gtest/test/gtest-death-test_test.cc @@ -35,6 +35,9 @@ #include <gtest/gtest.h> #include <gtest/internal/gtest-filepath.h> +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; + #if GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS @@ -143,7 +146,7 @@ class MayDie { // A member function that may die. void MemberFunction() const { if (should_die_) { - GTEST_LOG_(FATAL, "death inside MayDie::MemberFunction()."); + GTEST_LOG_(FATAL) << "death inside MayDie::MemberFunction()."; } } @@ -154,26 +157,26 @@ class MayDie { // A global function that's expected to die. void GlobalFunction() { - GTEST_LOG_(FATAL, "death inside GlobalFunction()."); + GTEST_LOG_(FATAL) << "death inside GlobalFunction()."; } // A non-void function that's expected to die. int NonVoidFunction() { - GTEST_LOG_(FATAL, "death inside NonVoidFunction()."); + GTEST_LOG_(FATAL) << "death inside NonVoidFunction()."; return 1; } // A unary function that may die. void DieIf(bool should_die) { if (should_die) { - GTEST_LOG_(FATAL, "death inside DieIf()."); + GTEST_LOG_(FATAL) << "death inside DieIf()."; } } // A binary function that may die. bool DieIfLessThan(int x, int y) { if (x < y) { - GTEST_LOG_(FATAL, "death inside DieIfLessThan()."); + GTEST_LOG_(FATAL) << "death inside DieIfLessThan()."; } return true; } @@ -188,7 +191,7 @@ void DeathTestSubroutine() { int DieInDebugElse12(int* sideeffect) { if (sideeffect) *sideeffect = 12; #ifndef NDEBUG - GTEST_LOG_(FATAL, "debug death inside DieInDebugElse12()"); + GTEST_LOG_(FATAL) << "debug death inside DieInDebugElse12()"; #endif // NDEBUG return 12; } @@ -271,28 +274,28 @@ TEST(ExitStatusPredicateTest, KilledBySignal) { // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. TEST_F(TestForDeathTest, SingleStatement) { - if (false) + if (AlwaysFalse()) // This would fail if executed; this is a compilation test only ASSERT_DEATH(return, ""); - if (true) + if (AlwaysTrue()) EXPECT_DEATH(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" ; - if (false) + if (AlwaysFalse()) ASSERT_DEATH(return, "") << "did not die"; - if (false) + if (AlwaysFalse()) ; else EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; } void DieWithEmbeddedNul() { - fprintf(stderr, "Hello%cworld.\n", '\0'); + fprintf(stderr, "Hello%cmy null world.\n", '\0'); fflush(stderr); _exit(1); } @@ -303,8 +306,8 @@ void DieWithEmbeddedNul() { TEST_F(TestForDeathTest, EmbeddedNulInMessage) { // TODO(wan@google.com): <regex.h> doesn't support matching strings // with embedded NUL characters - find a way to workaround it. - EXPECT_DEATH(DieWithEmbeddedNul(), "w.*ld"); - ASSERT_DEATH(DieWithEmbeddedNul(), "w.*ld"); + EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); + ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); } #endif // GTEST_USES_PCRE @@ -656,7 +659,11 @@ static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); -#if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW + // MinGW (as of MinGW 5.1.6 and MSYS 1.0.11) does not tag crashed + // processes with non-zero exit code and does not honor calls to + // SetErrorMode(SEM_NOGPFAULTERRORBOX) that are supposed to suppress + // error pop-ups. EXPECT_EXIT({ testing::GTEST_FLAG(catch_exceptions) = false; *static_cast<int*>(NULL) = 1; @@ -668,7 +675,9 @@ static void TestExitMacros() { *static_cast<int*>(NULL) = 1; }, testing::ExitedWithCode(0), "") << "This failure is expected."; }, "This failure is expected."); +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW +#if GTEST_OS_WINDOWS // Of all signals effects on the process exit code, only those of SIGABRT // are documented on Windows. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. @@ -824,9 +833,10 @@ void MockDeathTestFactory::SetParameters(bool create, // Sets test to NULL (if create_ is false) or to the address of a new // MockDeathTest object with parameters taken from the last call // to SetParameters (if create_ is true). Always returns true. -bool MockDeathTestFactory::Create(const char* statement, - const ::testing::internal::RE* regex, - const char* file, int line, +bool MockDeathTestFactory::Create(const char* /*statement*/, + const ::testing::internal::RE* /*regex*/, + const char* /*file*/, + int /*line*/, DeathTest** test) { test_deleted_ = false; if (create_) { @@ -1136,7 +1146,7 @@ using testing::internal::GetCapturedStderr; using testing::internal::String; // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still -// defined but do not rigger failures when death tests are not available on +// defined but do not trigger failures when death tests are not available on // the system. TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { // Empty statement will not crash, but that should not trigger a failure @@ -1148,16 +1158,89 @@ TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + // The streamed message should not be printed as there is no test failure. + CaptureStderr(); + EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); + CaptureStderr(); - ASSERT_DEATH_IF_SUPPORTED(;, ""); + ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT output = GetCapturedStderr(); ASSERT_TRUE(NULL != strstr(output.c_str(), "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); + + CaptureStderr(); + ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT + output = GetCapturedStderr(); + ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); +} + +void FuncWithAssert(int* n) { + ASSERT_DEATH_IF_SUPPORTED(return;, ""); + (*n)++; } +// Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current +// function (as ASSERT_DEATH does) if death tests are not supported. +TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { + int n = 0; + FuncWithAssert(&n); + EXPECT_EQ(1, n); +} #endif // GTEST_HAS_DEATH_TEST +// Tests that the death test macros expand to code which may or may not +// be followed by operator<<, and that in either case the complete text +// comprises only a single C++ statement. +// +// The syntax should work whether death tests are available or not. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { + if (AlwaysFalse()) + // This would fail if executed; this is a compilation test only + ASSERT_DEATH_IF_SUPPORTED(return, ""); + + if (AlwaysTrue()) + EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); + else + // This empty "else" branch is meant to ensure that EXPECT_DEATH + // doesn't expand into an "if" statement without an "else" + ; // NOLINT + + if (AlwaysFalse()) + ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; + + if (AlwaysFalse()) + ; // NOLINT + else + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; +} + +// Tests that conditional death test macros expand to code which interacts +// well with switch statements. +TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { +// Microsoft compiler usually complains about switch statements without +// case labels. We suppress that warning for this test. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4065) +#endif // _MSC_VER + + switch (0) + default: + ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") + << "exit in default switch handler"; + + switch (0) + case 0: + EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER +} + // Tests that a test case whose name ends with "DeathTest" works fine // on Windows. TEST(NotADeathTest, Test) { diff --git a/gtest/test/gtest-filepath_test.cc b/gtest/test/gtest-filepath_test.cc index adf9746..5bc4daf 100644 --- a/gtest/test/gtest-filepath_test.cc +++ b/gtest/test/gtest-filepath_test.cc @@ -50,17 +50,17 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE #include <windows.h> // NOLINT #elif GTEST_OS_WINDOWS #include <direct.h> // NOLINT -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE namespace testing { namespace internal { namespace { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // TODO(wan@google.com): Move these to the POSIX adapter section in // gtest-port.h. @@ -81,9 +81,7 @@ int _rmdir(const char* path) { return ret; } -#endif // _WIN32_WCE - -#ifndef _WIN32_WCE +#else TEST(GetCurrentDirTest, ReturnsCurrentDir) { const FilePath original_dir = FilePath::GetCurrentDir(); @@ -103,7 +101,7 @@ TEST(GetCurrentDirTest, ReturnsCurrentDir) { #endif } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE TEST(IsEmptyTest, ReturnsTrueForEmptyPath) { EXPECT_TRUE(FilePath("").IsEmpty()); @@ -156,7 +154,7 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) { // RemoveFileName "" -> "./" TEST(RemoveFileNameTest, EmptyName) { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // On Windows CE, we use the root as the current directory. EXPECT_STREQ(GTEST_PATH_SEP_, FilePath("").RemoveFileName().c_str()); @@ -344,12 +342,12 @@ TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) { } #endif // GTEST_OS_WINDOWS -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE // Windows CE _does_ consider an empty directory to exist. TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) { EXPECT_FALSE(FilePath("").DirectoryExists()); } -#endif // ! _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE TEST(DirectoryTest, CurrentDirectoryExists) { #if GTEST_OS_WINDOWS // We are on Windows. @@ -449,9 +447,8 @@ class DirectoryCreationTest : public Test { } String TempDir() const { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE return String("\\temp\\"); - #elif GTEST_OS_WINDOWS const char* temp_dir = posix::GetEnv("TEMP"); if (temp_dir == NULL || temp_dir[0] == '\0') @@ -462,7 +459,7 @@ class DirectoryCreationTest : public Test { return String::Format("%s\\", temp_dir); #else return String("/tmp/"); -#endif +#endif // GTEST_OS_WINDOWS_MOBILE } void CreateTextFile(const char* filename) { diff --git a/gtest/test/gtest-listener_test.cc b/gtest/test/gtest-listener_test.cc new file mode 100644 index 0000000..f12f518 --- /dev/null +++ b/gtest/test/gtest-listener_test.cc @@ -0,0 +1,322 @@ +// Copyright 2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) +// +// The Google C++ Testing Framework (Google Test) +// +// This file verifies Google Test event listeners receive events at the +// right times. + +#include <gtest/gtest.h> + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" // For Vector. +#undef GTEST_IMPLEMENTATION_ + +using ::testing::AddGlobalTestEnvironment; +using ::testing::Environment; +using ::testing::InitGoogleTest; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListener; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; +using ::testing::internal::String; +using ::testing::internal::Vector; + +// Used by tests to register their events. +Vector<String>* g_events = NULL; + +namespace testing { +namespace internal { + +class EventRecordingListener : public TestEventListener { + public: + EventRecordingListener(const char* name) : name_(name) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnTestProgramStart")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationStart") + << "(" << iteration << ")"; + g_events->PushBack(message.GetString()); + } + + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpStart")); + } + + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsSetUpEnd")); + } + + virtual void OnTestCaseStart(const TestCase& /*test_case*/) { + g_events->PushBack(GetFullMethodName("OnTestCaseStart")); + } + + virtual void OnTestStart(const TestInfo& /*test_info*/) { + g_events->PushBack(GetFullMethodName("OnTestStart")); + } + + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) { + g_events->PushBack(GetFullMethodName("OnTestPartResult")); + } + + virtual void OnTestEnd(const TestInfo& /*test_info*/) { + g_events->PushBack(GetFullMethodName("OnTestEnd")); + } + + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { + g_events->PushBack(GetFullMethodName("OnTestCaseEnd")); + } + + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownStart")); + } + + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnEnvironmentsTearDownEnd")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int iteration) { + Message message; + message << GetFullMethodName("OnTestIterationEnd") + << "(" << iteration << ")"; + g_events->PushBack(message.GetString()); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + g_events->PushBack(GetFullMethodName("OnTestProgramEnd")); + } + + private: + String GetFullMethodName(const char* name) { + Message message; + message << name_ << "." << name; + return message.GetString(); + } + + String name_; +}; + +class EnvironmentInvocationCatcher : public Environment { + protected: + virtual void SetUp() { + g_events->PushBack(String("Environment::SetUp")); + } + + virtual void TearDown() { + g_events->PushBack(String("Environment::TearDown")); + } +}; + +class ListenerTest : public Test { + protected: + static void SetUpTestCase() { + g_events->PushBack(String("ListenerTest::SetUpTestCase")); + } + + static void TearDownTestCase() { + g_events->PushBack(String("ListenerTest::TearDownTestCase")); + } + + virtual void SetUp() { + g_events->PushBack(String("ListenerTest::SetUp")); + } + + virtual void TearDown() { + g_events->PushBack(String("ListenerTest::TearDown")); + } +}; + +TEST_F(ListenerTest, DoesFoo) { + // Test execution order within a test case is not guaranteed so we are not + // recording the test name. + g_events->PushBack(String("ListenerTest::* Test Body")); + SUCCEED(); // Triggers OnTestPartResult. +} + +TEST_F(ListenerTest, DoesBar) { + g_events->PushBack(String("ListenerTest::* Test Body")); + SUCCEED(); // Triggers OnTestPartResult. +} + +} // namespace internal + +} // namespace testing + +using ::testing::internal::EnvironmentInvocationCatcher; +using ::testing::internal::EventRecordingListener; + +void VerifyResults(const Vector<String>& data, + const char* const* expected_data, + int expected_data_size) { + const int actual_size = data.size(); + // If the following assertion fails, a new entry will be appended to + // data. Hence we save data.size() first. + EXPECT_EQ(expected_data_size, actual_size); + + // Compares the common prefix. + const int shorter_size = expected_data_size <= actual_size ? + expected_data_size : actual_size; + int i = 0; + for (; i < shorter_size; ++i) { + ASSERT_STREQ(expected_data[i], data.GetElement(i).c_str()) + << "at position " << i; + } + + // Prints extra elements in the actual data. + for (; i < actual_size; ++i) { + printf(" Actual event #%d: %s\n", i, data.GetElement(i).c_str()); + } +} + +int main(int argc, char **argv) { + Vector<String> events; + g_events = &events; + InitGoogleTest(&argc, argv); + + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("1st")); + UnitTest::GetInstance()->listeners().Append( + new EventRecordingListener("2nd")); + + AddGlobalTestEnvironment(new EnvironmentInvocationCatcher); + + GTEST_CHECK_(events.size() == 0) + << "AddGlobalTestEnvironment should not generate any events itself."; + + ::testing::GTEST_FLAG(repeat) = 2; + int ret_val = RUN_ALL_TESTS(); + + const char* const expected_events[] = { + "1st.OnTestProgramStart", + "2nd.OnTestProgramStart", + "1st.OnTestIterationStart(0)", + "2nd.OnTestIterationStart(0)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(0)", + "1st.OnTestIterationEnd(0)", + "1st.OnTestIterationStart(1)", + "2nd.OnTestIterationStart(1)", + "1st.OnEnvironmentsSetUpStart", + "2nd.OnEnvironmentsSetUpStart", + "Environment::SetUp", + "2nd.OnEnvironmentsSetUpEnd", + "1st.OnEnvironmentsSetUpEnd", + "1st.OnTestCaseStart", + "2nd.OnTestCaseStart", + "ListenerTest::SetUpTestCase", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "1st.OnTestStart", + "2nd.OnTestStart", + "ListenerTest::SetUp", + "ListenerTest::* Test Body", + "1st.OnTestPartResult", + "2nd.OnTestPartResult", + "ListenerTest::TearDown", + "2nd.OnTestEnd", + "1st.OnTestEnd", + "ListenerTest::TearDownTestCase", + "2nd.OnTestCaseEnd", + "1st.OnTestCaseEnd", + "1st.OnEnvironmentsTearDownStart", + "2nd.OnEnvironmentsTearDownStart", + "Environment::TearDown", + "2nd.OnEnvironmentsTearDownEnd", + "1st.OnEnvironmentsTearDownEnd", + "2nd.OnTestIterationEnd(1)", + "1st.OnTestIterationEnd(1)", + "2nd.OnTestProgramEnd", + "1st.OnTestProgramEnd" + }; + VerifyResults(events, + expected_events, + sizeof(expected_events)/sizeof(expected_events[0])); + + // We need to check manually for ad hoc test failures that happen after + // RUN_ALL_TESTS finishes. + if (UnitTest::GetInstance()->Failed()) + ret_val = 1; + + return ret_val; +} diff --git a/gtest/test/gtest-options_test.cc b/gtest/test/gtest-options_test.cc index 43c6d22..31ae327 100644 --- a/gtest/test/gtest-options_test.cc +++ b/gtest/test/gtest-options_test.cc @@ -40,11 +40,11 @@ #include <gtest/gtest.h> -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE #include <windows.h> #elif GTEST_OS_WINDOWS #include <direct.h> -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is @@ -130,7 +130,7 @@ TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { TEST(OutputFileHelpersTest, GetCurrentExecutableName) { const FilePath executable = GetCurrentExecutableName(); const char* const exe_str = executable.c_str(); -#if defined(_WIN32_WCE) || GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS ASSERT_TRUE(_strcmpi("gtest-options_test", exe_str) == 0 || _strcmpi("gtest-options-ex_test", exe_str) == 0 || _strcmpi("gtest_all_test", exe_str) == 0) @@ -143,7 +143,7 @@ TEST(OutputFileHelpersTest, GetCurrentExecutableName) { String(exe_str) == "gtest_all_test" || String(exe_str) == "lt-gtest_all_test") << "GetCurrentExecutableName() returns " << exe_str; -#endif +#endif // GTEST_OS_WINDOWS } class XmlOutputChangeDirTest : public Test { diff --git a/gtest/test/gtest-port_test.cc b/gtest/test/gtest-port_test.cc index d980b7c..df59f9e 100644 --- a/gtest/test/gtest-port_test.cc +++ b/gtest/test/gtest-port_test.cc @@ -54,16 +54,16 @@ namespace testing { namespace internal { TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { - if (false) + if (AlwaysFalse()) GTEST_CHECK_(false) << "This should never be executed; " "It's a compilation test only."; - if (true) + if (AlwaysTrue()) GTEST_CHECK_(true); else ; // NOLINT - if (false) + if (AlwaysFalse()) ; // NOLINT else GTEST_CHECK_(true) << ""; @@ -133,8 +133,6 @@ TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { } #endif // GTEST_OS_MAC -#if GTEST_HAS_DEATH_TEST - TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; const char regex[] = @@ -145,9 +143,12 @@ TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { #endif // _MSC_VER ".*a_false_condition.*Extra info.*"; - EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info", regex); + EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", + regex); } +#if GTEST_HAS_DEATH_TEST + TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { EXPECT_EXIT({ GTEST_CHECK_(true) << "Extra info"; diff --git a/gtest/test/gtest-test-part_test.cc b/gtest/test/gtest-test-part_test.cc index 93fe156..403c184 100644 --- a/gtest/test/gtest-test-part_test.cc +++ b/gtest/test/gtest-test-part_test.cc @@ -38,10 +38,6 @@ using testing::Test; using testing::TestPartResult; using testing::TestPartResultArray; -using testing::TPRT_FATAL_FAILURE; -using testing::TPRT_NONFATAL_FAILURE; -using testing::TPRT_SUCCESS; - namespace { // Tests the TestPartResult class. @@ -50,18 +46,18 @@ namespace { class TestPartResultTest : public Test { protected: TestPartResultTest() - : r1_(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"), - r2_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure!"), - r3_(TPRT_FATAL_FAILURE, NULL, -1, "Failure!") {} + : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"), + r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"), + r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {} TestPartResult r1_, r2_, r3_; }; // Tests TestPartResult::type(). TEST_F(TestPartResultTest, type) { - EXPECT_EQ(TPRT_SUCCESS, r1_.type()); - EXPECT_EQ(TPRT_NONFATAL_FAILURE, r2_.type()); - EXPECT_EQ(TPRT_FATAL_FAILURE, r3_.type()); + EXPECT_EQ(TestPartResult::kSuccess, r1_.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type()); + EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type()); } // Tests TestPartResult::file_name(). @@ -114,8 +110,8 @@ TEST_F(TestPartResultTest, NonfatallyFailed) { class TestPartResultArrayTest : public Test { protected: TestPartResultArrayTest() - : r1_(TPRT_NONFATAL_FAILURE, "foo/bar.cc", -1, "Failure 1"), - r2_(TPRT_FATAL_FAILURE, "foo/bar.cc", -1, "Failure 2") {} + : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"), + r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {} const TestPartResult r1_, r2_; }; @@ -146,8 +142,6 @@ TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) { EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message()); } -#if GTEST_HAS_DEATH_TEST - typedef TestPartResultArrayTest TestPartResultArrayDeathTest; // Tests that the program dies when GetTestPartResult() is called with @@ -156,12 +150,10 @@ TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) { TestPartResultArray results; results.Append(r1_); - EXPECT_DEATH(results.GetTestPartResult(-1), ""); - EXPECT_DEATH(results.GetTestPartResult(1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), ""); + EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), ""); } -#endif // GTEST_HAS_DEATH_TEST - // TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper. } // namespace diff --git a/gtest/test/gtest-typed-test_test.cc b/gtest/test/gtest-typed-test_test.cc index 8e86ac8..4b6e971 100644 --- a/gtest/test/gtest-typed-test_test.cc +++ b/gtest/test/gtest-typed-test_test.cc @@ -29,8 +29,8 @@ // // Author: wan@google.com (Zhanyong Wan) -#include <list> #include <set> +#include <vector> #include "test/gtest-typed-test_test.h" #include <gtest/gtest.h> @@ -57,7 +57,9 @@ class CommonTest : public Test { // This 'protected:' is optional. There's no harm in making all // members of this fixture class template public. protected: - typedef std::list<T> List; + // We used to use std::list here, but switched to std::vector since + // MSVC's <list> doesn't compile cleanly with /W4. + typedef std::vector<T> Vector; typedef std::set<int> IntSet; CommonTest() : value_(1) {} @@ -99,7 +101,7 @@ TYPED_TEST(CommonTest, ValuesAreCorrect) { // Typedefs in the fixture class template can be visited via the // "typename TestFixture::" prefix. - typename TestFixture::List empty; + typename TestFixture::Vector empty; EXPECT_EQ(0U, empty.size()); typename TestFixture::IntSet empty2; @@ -198,24 +200,22 @@ TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); } -#if GTEST_HAS_DEATH_TEST - typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), "foo\\.cc.1.?: Test A is listed more than once\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), "foo\\.cc.1.?: No test named D can be found in this test case\\."); } TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), "foo\\.cc.1.?: You forgot to list test B\\."); } @@ -224,14 +224,12 @@ TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { // a run-time error if the test case has been registered. TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); - EXPECT_DEATH( + EXPECT_DEATH_IF_SUPPORTED( state_.AddTestName("foo.cc", 2, "FooTest", "D"), "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" "\\(FooTest, \\.\\.\\.\\)\\."); } -#endif // GTEST_HAS_DEATH_TEST - // Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, // and SetUp()/TearDown() work correctly in type-parameterized tests. @@ -318,7 +316,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types<double>); // Tests that the same type-parameterized test case can be // instantiated in different translation units linked together. // (ContainerTest is also instantiated in gtest-typed-test_test.cc.) -typedef Types<std::list<double>, std::set<char> > MyContainers; +typedef Types<std::vector<double>, std::set<char> > MyContainers; INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); // Tests that a type-parameterized test case can be defined and diff --git a/gtest/test/gtest-unittest-api_test.cc b/gtest/test/gtest-unittest-api_test.cc index 658e298..7e0f8f8 100644 --- a/gtest/test/gtest-unittest-api_test.cc +++ b/gtest/test/gtest-unittest-api_test.cc @@ -38,21 +38,7 @@ #include <string.h> // For strcmp. #include <algorithm> -using ::testing::AddGlobalTestEnvironment; -using ::testing::Environment; using ::testing::InitGoogleTest; -using ::testing::Test; -using ::testing::TestInfo; -using ::testing::TestPartResult; -using ::testing::UnitTest; -using ::testing::internal::TestCase; -using ::testing::internal::TestProperty; - -#if GTEST_HAS_TYPED_TEST -using ::testing::Types; -using ::testing::internal::GetTypeName; -using ::testing::internal::String; -#endif // GTEST_HAS_TYPED_TEST namespace testing { namespace internal { @@ -64,20 +50,20 @@ struct LessByName { } }; -class UnitTestAccessor { +class UnitTestHelper { public: // Returns the array of pointers to all test cases sorted by the test case // name. The caller is responsible for deleting the array. static TestCase const** const GetSortedTestCases() { - UnitTest* unit_test = UnitTest::GetInstance(); + UnitTest& unit_test = *UnitTest::GetInstance(); TestCase const** const test_cases = - new const TestCase*[unit_test->total_test_case_count()]; + new const TestCase*[unit_test.total_test_case_count()]; - for (int i = 0; i < unit_test->total_test_case_count(); ++i) - test_cases[i] = unit_test->GetTestCase(i); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + test_cases[i] = unit_test.GetTestCase(i); std::sort(test_cases, - test_cases + unit_test->total_test_case_count(), + test_cases + unit_test.total_test_case_count(), LessByName<TestCase>()); return test_cases; } @@ -85,9 +71,9 @@ class UnitTestAccessor { // Returns the test case by its name. The caller doesn't own the returned // pointer. static const TestCase* FindTestCase(const char* name) { - UnitTest* unit_test = UnitTest::GetInstance(); - for (int i = 0; i < unit_test->total_test_case_count(); ++i) { - const TestCase* test_case = unit_test->GetTestCase(i); + UnitTest& unit_test = *UnitTest::GetInstance(); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase* test_case = unit_test.GetTestCase(i); if (0 == strcmp(test_case->name(), name)) return test_case; } @@ -104,19 +90,12 @@ class UnitTestAccessor { for (int i = 0; i < test_case->total_test_count(); ++i) tests[i] = test_case->GetTestInfo(i); - std::sort(tests, - tests + test_case->total_test_count(), + std::sort(tests, tests + test_case->total_test_count(), LessByName<TestInfo>()); return tests; } }; -// TODO(vladl@google.com): Put tests into the internal namespace after -// UnitTest methods are published. -} // namespace internal - -using internal::UnitTestAccessor; - #if GTEST_HAS_TYPED_TEST template <typename T> class TestCaseWithCommentTest : public Test {}; TYPED_TEST_CASE(TestCaseWithCommentTest, Types<int>); @@ -147,7 +126,7 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) { EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count()); EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count()); - const TestCase** const test_cases = UnitTestAccessor::GetSortedTestCases(); + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); EXPECT_STREQ("ApiTest", test_cases[0]->name()); EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); @@ -165,7 +144,7 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) { } TEST(ApiTest, TestCaseImmutableAccessorsWork) { - const TestCase* test_case = UnitTestAccessor::FindTestCase("ApiTest"); + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("ApiTest", test_case->name()); @@ -175,7 +154,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { EXPECT_EQ(3, test_case->test_to_run_count()); ASSERT_EQ(4, test_case->total_test_count()); - const TestInfo** tests = UnitTestAccessor::GetSortedTests(test_case); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); @@ -205,7 +184,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { tests = NULL; #if GTEST_HAS_TYPED_TEST - test_case = UnitTestAccessor::FindTestCase("TestCaseWithCommentTest/0"); + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); @@ -215,7 +194,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { EXPECT_EQ(1, test_case->test_to_run_count()); ASSERT_EQ(1, test_case->total_test_count()); - tests = UnitTestAccessor::GetSortedTests(test_case); + tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); @@ -229,7 +208,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) { } TEST(ApiTest, TestCaseDisabledAccessorsWork) { - const TestCase* test_case = UnitTestAccessor::FindTestCase("DISABLED_Test"); + const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test"); ASSERT_TRUE(test_case != NULL); EXPECT_STREQ("DISABLED_Test", test_case->name()); @@ -265,7 +244,7 @@ class FinalSuccessChecker : public Environment { EXPECT_FALSE(unit_test->Failed()); ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count()); - const TestCase** const test_cases = UnitTestAccessor::GetSortedTestCases(); + const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); EXPECT_STREQ("ApiTest", test_cases[0]->name()); EXPECT_STREQ("", test_cases[0]->comment()); @@ -298,8 +277,8 @@ class FinalSuccessChecker : public Environment { EXPECT_FALSE(test_cases[2]->Failed()); #endif // GTEST_HAS_TYPED_TEST - const TestCase* test_case = UnitTestAccessor::FindTestCase("ApiTest"); - const TestInfo** tests = UnitTestAccessor::GetSortedTests(test_case); + const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); + const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); EXPECT_FALSE(tests[0]->should_run()); @@ -334,8 +313,8 @@ class FinalSuccessChecker : public Environment { delete[] tests; #if GTEST_HAS_TYPED_TEST - test_case = UnitTestAccessor::FindTestCase("TestCaseWithCommentTest/0"); - tests = UnitTestAccessor::GetSortedTests(test_case); + test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0"); + tests = UnitTestHelper::GetSortedTests(test_case); EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); @@ -352,12 +331,13 @@ class FinalSuccessChecker : public Environment { } }; +} // namespace internal } // namespace testing int main(int argc, char **argv) { InitGoogleTest(&argc, argv); - AddGlobalTestEnvironment(new testing::FinalSuccessChecker()); + AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker()); return RUN_ALL_TESTS(); } diff --git a/gtest/test/gtest_env_var_test.py b/gtest/test/gtest_env_var_test.py index 19fd810..f8250d4 100755 --- a/gtest/test/gtest_env_var_test.py +++ b/gtest/test/gtest_env_var_test.py @@ -85,7 +85,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('break_on_failure', '1', '0') TestFlag('color', 'yes', 'auto') TestFlag('filter', 'FooTest.Bar', '*') - TestFlag('output', 'tmp/foo.xml', '') + TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('print_time', '0', '1') TestFlag('repeat', '999', '1') TestFlag('throw_on_failure', '1', '0') diff --git a/gtest/test/gtest_filter_unittest_.cc b/gtest/test/gtest_filter_unittest_.cc index 3cbddcf..325504f 100644 --- a/gtest/test/gtest_filter_unittest_.cc +++ b/gtest/test/gtest_filter_unittest_.cc @@ -92,19 +92,13 @@ TEST(BazTest, DISABLED_TestC) { // Test case HasDeathTest TEST(HasDeathTest, Test1) { -#if GTEST_HAS_DEATH_TEST - EXPECT_DEATH({exit(1);}, - ".*"); -#endif // GTEST_HAS_DEATH_TEST + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); } // We need at least two death tests to make sure that the all death tests // aren't on the first shard. TEST(HasDeathTest, Test2) { -#if GTEST_HAS_DEATH_TEST - EXPECT_DEATH({exit(1);}, - ".*"); -#endif // GTEST_HAS_DEATH_TEST + EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); } // Test case FoobarTest diff --git a/gtest/test/gtest_repeat_test.cc b/gtest/test/gtest_repeat_test.cc index 39a0601..df6868b 100644 --- a/gtest/test/gtest_repeat_test.cc +++ b/gtest/test/gtest_repeat_test.cc @@ -64,14 +64,14 @@ namespace { do {\ const int expected_val = (expected);\ const int actual_val = (actual);\ - if (expected_val != actual_val) {\ + if (::testing::internal::IsTrue(expected_val != actual_val)) {\ ::std::cout << "Value of: " #actual "\n"\ << " Actual: " << actual_val << "\n"\ << "Expected: " #expected "\n"\ << "Which is: " << expected_val << "\n";\ abort();\ }\ - } while(false) + } while(::testing::internal::AlwaysFalse()) // Used for verifying that global environment set-up and tear-down are @@ -112,13 +112,11 @@ int g_death_test_count = 0; TEST(BarDeathTest, ThreadSafeAndFast) { g_death_test_count++; -#if GTEST_HAS_DEATH_TEST GTEST_FLAG(death_test_style) = "threadsafe"; - EXPECT_DEATH(abort(), ""); + EXPECT_DEATH_IF_SUPPORTED(abort(), ""); GTEST_FLAG(death_test_style) = "fast"; - EXPECT_DEATH(abort(), ""); -#endif // GTEST_HAS_DEATH_TEST + EXPECT_DEATH_IF_SUPPORTED(abort(), ""); } #if GTEST_HAS_PARAM_TEST diff --git a/gtest/test/gtest_shuffle_test.py b/gtest/test/gtest_shuffle_test.py new file mode 100755 index 0000000..a870a01 --- /dev/null +++ b/gtest/test/gtest_shuffle_test.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +# +# Copyright 2009 Google Inc. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Verifies that test shuffling works.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import gtest_test_utils + +# Command to run the gtest_shuffle_test_ program. +COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_') + +# The environment variables for test sharding. +TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' +SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' + +TEST_FILTER = 'A*.A:A*.B:C*' + +ALL_TESTS = [] +ACTIVE_TESTS = [] +FILTERED_TESTS = [] +SHARDED_TESTS = [] + +SHUFFLED_ALL_TESTS = [] +SHUFFLED_ACTIVE_TESTS = [] +SHUFFLED_FILTERED_TESTS = [] +SHUFFLED_SHARDED_TESTS = [] + + +def AlsoRunDisabledTestsFlag(): + return '--gtest_also_run_disabled_tests' + + +def FilterFlag(test_filter): + return '--gtest_filter=%s' % (test_filter,) + + +def RepeatFlag(n): + return '--gtest_repeat=%s' % (n,) + + +def ShuffleFlag(): + return '--gtest_shuffle' + + +def RandomSeedFlag(n): + return '--gtest_random_seed=%s' % (n,) + + +def RunAndReturnOutput(extra_env, args): + """Runs the test program and returns its output.""" + + try: + original_env = os.environ.copy() + os.environ.update(extra_env) + return gtest_test_utils.Subprocess([COMMAND] + args).output + finally: + for key in extra_env.iterkeys(): + if key in original_env: + os.environ[key] = original_env[key] + else: + del os.environ[key] + + +def GetTestsForAllIterations(extra_env, args): + """Runs the test program and returns a list of test lists. + + Args: + extra_env: a map from environment variables to their values + args: command line flags to pass to gtest_shuffle_test_ + + Returns: + A list where the i-th element is the list of tests run in the i-th + test iteration. + """ + + test_iterations = [] + for line in RunAndReturnOutput(extra_env, args).split('\n'): + if line.startswith('----'): + tests = [] + test_iterations.append(tests) + elif line.strip(): + tests.append(line.strip()) # 'TestCaseName.TestName' + + return test_iterations + + +def GetTestCases(tests): + """Returns a list of test cases in the given full test names. + + Args: + tests: a list of full test names + + Returns: + A list of test cases from 'tests', in their original order. + Consecutive duplicates are removed. + """ + + test_cases = [] + for test in tests: + test_case = test.split('.')[0] + if not test_case in test_cases: + test_cases.append(test_case) + + return test_cases + + +def CalculateTestLists(): + """Calculates the list of tests run under different flags.""" + + if not ALL_TESTS: + ALL_TESTS.extend( + GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0]) + + if not ACTIVE_TESTS: + ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0]) + + if not FILTERED_TESTS: + FILTERED_TESTS.extend( + GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0]) + + if not SHARDED_TESTS: + SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [])[0]) + + if not SHUFFLED_ALL_TESTS: + SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations( + {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_ACTIVE_TESTS: + SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + if not SHUFFLED_FILTERED_TESTS: + SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0]) + + if not SHUFFLED_SHARDED_TESTS: + SHUFFLED_SHARDED_TESTS.extend( + GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(1)])[0]) + + +class GTestShuffleUnitTest(gtest_test_utils.TestCase): + """Tests test shuffling.""" + + def setUp(self): + CalculateTestLists() + + def testShufflePreservesNumberOfTests(self): + self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS)) + self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS)) + self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS)) + self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS)) + + def testShuffleChangesTestOrder(self): + self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS) + self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS) + self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS, + SHUFFLED_FILTERED_TESTS) + self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS, + SHUFFLED_SHARDED_TESTS) + + def testShuffleChangesTestCaseOrder(self): + self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS), + GetTestCases(SHUFFLED_ALL_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS), + GetTestCases(SHUFFLED_ACTIVE_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS), + GetTestCases(SHUFFLED_FILTERED_TESTS)) + self.assert_( + GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS), + GetTestCases(SHUFFLED_SHARDED_TESTS)) + + def testShuffleDoesNotRepeatTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test), + '%s appears more than once' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test), + '%s appears more than once' % (test,)) + + def testShuffleDoesNotCreateNewTest(self): + for test in SHUFFLED_ALL_TESTS: + self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_ACTIVE_TESTS: + self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_FILTERED_TESTS: + self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,)) + for test in SHUFFLED_SHARDED_TESTS: + self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,)) + + def testShuffleIncludesAllTests(self): + for test in ALL_TESTS: + self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,)) + for test in ACTIVE_TESTS: + self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,)) + for test in FILTERED_TESTS: + self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,)) + for test in SHARDED_TESTS: + self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,)) + + def testShuffleLeavesDeathTestsAtFront(self): + non_death_test_found = False + for test in SHUFFLED_ACTIVE_TESTS: + if 'DeathTest.' in test: + self.assert_(not non_death_test_found, + '%s appears after a non-death test' % (test,)) + else: + non_death_test_found = True + + def _VerifyTestCasesDoNotInterleave(self, tests): + test_cases = [] + for test in tests: + [test_case, _] = test.split('.') + if test_cases and test_cases[-1] != test_case: + test_cases.append(test_case) + self.assertEqual(1, test_cases.count(test_case), + 'Test case %s is not grouped together in %s' % + (test_case, tests)) + + def testShuffleDoesNotInterleaveTestCases(self): + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS) + self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS) + + def testShuffleRestoresOrderAfterEachIteration(self): + # Get the test lists in all 3 iterations, using random seed 1, 2, + # and 3 respectively. Google Test picks a different seed in each + # iteration, and this test depends on the current implementation + # picking successive numbers. This dependency is not ideal, but + # makes the test much easier to write. + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + # Make sure running the tests with random seed 1 gets the same + # order as in iteration 1 above. + [tests_with_seed1] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1)]) + self.assertEqual(tests_in_iteration1, tests_with_seed1) + + # Make sure running the tests with random seed 2 gets the same + # order as in iteration 2 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 2. + [tests_with_seed2] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(2)]) + self.assertEqual(tests_in_iteration2, tests_with_seed2) + + # Make sure running the tests with random seed 3 gets the same + # order as in iteration 3 above. Success means that Google Test + # correctly restores the test order before re-shuffling at the + # beginning of iteration 3. + [tests_with_seed3] = GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(3)]) + self.assertEqual(tests_in_iteration3, tests_with_seed3) + + def testShuffleGeneratesNewOrderInEachIteration(self): + [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = ( + GetTestsForAllIterations( + {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)])) + + self.assert_(tests_in_iteration1 != tests_in_iteration2, + tests_in_iteration1) + self.assert_(tests_in_iteration1 != tests_in_iteration3, + tests_in_iteration1) + self.assert_(tests_in_iteration2 != tests_in_iteration3, + tests_in_iteration2) + + def testShuffleShardedTestsPreservesPartition(self): + # If we run M tests on N shards, the same M tests should be run in + # total, regardless of the random seeds used by the shards. + [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '0'}, + [ShuffleFlag(), RandomSeedFlag(1)]) + [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '1'}, + [ShuffleFlag(), RandomSeedFlag(20)]) + [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3', + SHARD_INDEX_ENV_VAR: '2'}, + [ShuffleFlag(), RandomSeedFlag(25)]) + sorted_sharded_tests = tests1 + tests2 + tests3 + sorted_sharded_tests.sort() + sorted_active_tests = [] + sorted_active_tests.extend(ACTIVE_TESTS) + sorted_active_tests.sort() + self.assertEqual(sorted_active_tests, sorted_sharded_tests) + +if __name__ == '__main__': + gtest_test_utils.Main() diff --git a/gtest/test/gtest_shuffle_test_.cc b/gtest/test/gtest_shuffle_test_.cc new file mode 100644 index 0000000..53ecf77 --- /dev/null +++ b/gtest/test/gtest_shuffle_test_.cc @@ -0,0 +1,104 @@ +// Copyright 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Verifies that test shuffling works. + +#include <gtest/gtest.h> + +namespace { + +using ::testing::EmptyTestEventListener; +using ::testing::InitGoogleTest; +using ::testing::Message; +using ::testing::Test; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::UnitTest; +using ::testing::internal::String; +using ::testing::internal::scoped_ptr; + +// The test methods are empty, as the sole purpose of this program is +// to print the test names before/after shuffling. + +class A : public Test {}; +TEST_F(A, A) {} +TEST_F(A, B) {} + +TEST(ADeathTest, A) {} +TEST(ADeathTest, B) {} +TEST(ADeathTest, C) {} + +TEST(B, A) {} +TEST(B, B) {} +TEST(B, C) {} +TEST(B, DISABLED_D) {} +TEST(B, DISABLED_E) {} + +TEST(BDeathTest, A) {} +TEST(BDeathTest, B) {} + +TEST(C, A) {} +TEST(C, B) {} +TEST(C, C) {} +TEST(C, DISABLED_D) {} + +TEST(CDeathTest, A) {} + +TEST(DISABLED_D, A) {} +TEST(DISABLED_D, DISABLED_B) {} + +// This printer prints the full test names only, starting each test +// iteration with a "----" marker. +class TestNamePrinter : public EmptyTestEventListener { + public: + virtual void OnTestIterationStart(const UnitTest& /* unit_test */, + int /* iteration */) { + printf("----\n"); + } + + virtual void OnTestStart(const TestInfo& test_info) { + printf("%s.%s\n", test_info.test_case_name(), test_info.name()); + } +}; + +} // namespace + +int main(int argc, char **argv) { + InitGoogleTest(&argc, argv); + + // Replaces the default printer with TestNamePrinter, which prints + // the test name only. + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new TestNamePrinter); + + return RUN_ALL_TESTS(); +} diff --git a/gtest/test/gtest_stress_test.cc b/gtest/test/gtest_stress_test.cc index 57ea75a..0034bb8 100644 --- a/gtest/test/gtest_stress_test.cc +++ b/gtest/test/gtest_stress_test.cc @@ -46,7 +46,6 @@ namespace testing { namespace { using internal::String; -using internal::TestProperty; using internal::TestPropertyKeyIs; using internal::Vector; diff --git a/gtest/test/gtest_unittest.cc b/gtest/test/gtest_unittest.cc index 2c08720..5c69b46 100644 --- a/gtest/test/gtest_unittest.cc +++ b/gtest/test/gtest_unittest.cc @@ -80,23 +80,37 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { namespace testing { namespace internal { -const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); +bool ShouldUseColor(bool stdout_is_tty); +const char* FormatTimeInMillisAsSeconds(TimeInMillis ms); bool ParseInt32Flag(const char* str, const char* flag, Int32* value); -} // namespace internal -} // namespace testing +// Provides access to otherwise private parts of the TestEventListeners class +// that are needed to test it. +class TestEventListenersAccessor { + public: + static TestEventListener* GetRepeater(TestEventListeners* listeners) { + return listeners->repeater(); + } -using testing::internal::FormatTimeInMillisAsSeconds; -using testing::internal::ParseInt32Flag; + static void SetDefaultResultPrinter(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultResultPrinter(listener); + } + static void SetDefaultXmlGenerator(TestEventListeners* listeners, + TestEventListener* listener) { + listeners->SetDefaultXmlGenerator(listener); + } -namespace testing { + static bool EventForwardingEnabled(const TestEventListeners& listeners) { + return listeners.EventForwardingEnabled(); + } -GTEST_DECLARE_string_(output); -GTEST_DECLARE_string_(color); + static void SuppressEventForwarding(TestEventListeners* listeners) { + listeners->SuppressEventForwarding(); + } +}; -namespace internal { -bool ShouldUseColor(bool stdout_is_tty); } // namespace internal } // namespace testing @@ -104,6 +118,7 @@ using testing::AssertionFailure; using testing::AssertionResult; using testing::AssertionSuccess; using testing::DoubleLE; +using testing::EmptyTestEventListener; using testing::FloatLE; using testing::GTEST_FLAG(also_run_disabled_tests); using testing::GTEST_FLAG(break_on_failure); @@ -125,19 +140,21 @@ using testing::IsSubstring; using testing::Message; using testing::ScopedFakeTestPartResultReporter; using testing::StaticAssertTypeEq; -using testing::TPRT_FATAL_FAILURE; -using testing::TPRT_NONFATAL_FAILURE; -using testing::TPRT_SUCCESS; using testing::Test; +using testing::TestEventListeners; +using testing::TestCase; using testing::TestPartResult; using testing::TestPartResultArray; +using testing::TestProperty; +using testing::TestResult; using testing::UnitTest; -using testing::internal::kMaxRandomSeed; -using testing::internal::kTestTypeIdInGoogleTest; +using testing::internal::AlwaysFalse; +using testing::internal::AlwaysTrue; using testing::internal::AppendUserMessage; using testing::internal::CodePointToUtf8; using testing::internal::EqFailure; using testing::internal::FloatingPoint; +using testing::internal::FormatTimeInMillisAsSeconds; using testing::internal::GTestFlagSaver; using testing::internal::GetCurrentOsStackTraceExceptTop; using testing::internal::GetNextRandomSeed; @@ -147,19 +164,34 @@ using testing::internal::GetTypeId; using testing::internal::GetUnitTestImpl; using testing::internal::Int32; using testing::internal::Int32FromEnvOrDie; +using testing::internal::ParseInt32Flag; using testing::internal::ShouldRunTestOnShard; using testing::internal::ShouldShard; using testing::internal::ShouldUseColor; using testing::internal::StreamableToString; using testing::internal::String; -using testing::internal::TestCase; -using testing::internal::TestProperty; -using testing::internal::TestResult; +using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::ThreadLocal; +using testing::internal::UInt32; using testing::internal::Vector; using testing::internal::WideStringToUtf8; +using testing::internal::kMaxRandomSeed; using testing::internal::kTestTypeIdInGoogleTest; +using testing::internal::scoped_ptr; + +class TestingVector : public Vector<int> { +}; + +::std::ostream& operator<<(::std::ostream& os, + const TestingVector& vector) { + os << "{ "; + for (int i = 0; i < vector.size(); i++) { + os << vector.GetElement(i) << " "; + } + os << "}"; + return os; +} // This line tests that we can define tests in an unnamed namespace. namespace { @@ -472,6 +504,49 @@ TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) { } #endif // !GTEST_WIDE_STRING_USES_UTF16_ +// Tests the Random class. + +TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) { + testing::internal::Random random(42); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(0), + "Cannot generate a number in the range \\[0, 0\\)"); + EXPECT_DEATH_IF_SUPPORTED( + random.Generate(testing::internal::Random::kMaxRange + 1), + "Generation of a number in \\[0, 2147483649\\) was requested, " + "but this can only generate numbers in \\[0, 2147483648\\)"); +} + +TEST(RandomTest, GeneratesNumbersWithinRange) { + const UInt32 kRange = 10000; + testing::internal::Random random(12345); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i; + } + + testing::internal::Random random2(testing::internal::Random::kMaxRange); + for (int i = 0; i < 10; i++) { + EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i; + } +} + +TEST(RandomTest, RepeatsWhenReseeded) { + const int kSeed = 123; + const int kArraySize = 10; + const UInt32 kRange = 10000; + UInt32 values[kArraySize]; + + testing::internal::Random random(kSeed); + for (int i = 0; i < kArraySize; i++) { + values[i] = random.Generate(kRange); + } + + random.Reseed(kSeed); + for (int i = 0; i < kArraySize; i++) { + EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i; + } +} + // Tests the Vector class template. // Tests Vector::Clear(). @@ -615,6 +690,53 @@ TEST(VectorTest, GetElementOr) { EXPECT_EQ('x', a.GetElementOr(2, 'x')); } +TEST(VectorTest, Swap) { + Vector<int> a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + + // Swaps an element with itself. + a.Swap(0, 0); + ASSERT_EQ(0, a.GetElement(0)); + ASSERT_EQ(1, a.GetElement(1)); + ASSERT_EQ(2, a.GetElement(2)); + + // Swaps two different elements where the indices go up. + a.Swap(0, 1); + ASSERT_EQ(1, a.GetElement(0)); + ASSERT_EQ(0, a.GetElement(1)); + ASSERT_EQ(2, a.GetElement(2)); + + // Swaps two different elements where the indices go down. + a.Swap(2, 0); + ASSERT_EQ(2, a.GetElement(0)); + ASSERT_EQ(0, a.GetElement(1)); + ASSERT_EQ(1, a.GetElement(2)); +} + +TEST(VectorTest, Clone) { + // Clones an empty Vector. + Vector<int> a; + scoped_ptr<Vector<int> > empty(a.Clone()); + EXPECT_EQ(0, empty->size()); + + // Clones a singleton. + a.PushBack(42); + scoped_ptr<Vector<int> > singleton(a.Clone()); + ASSERT_EQ(1, singleton->size()); + EXPECT_EQ(42, singleton->GetElement(0)); + + // Clones a Vector with more elements. + a.PushBack(43); + a.PushBack(44); + scoped_ptr<Vector<int> > big(a.Clone()); + ASSERT_EQ(3, big->size()); + EXPECT_EQ(42, big->GetElement(0)); + EXPECT_EQ(43, big->GetElement(1)); + EXPECT_EQ(44, big->GetElement(2)); +} + // Tests Vector::Erase(). TEST(VectorDeathTest, Erase) { Vector<int> a; @@ -678,23 +800,260 @@ TEST(VectorDeathTest, Erase) { } // Tests the GetElement accessor. -TEST(ListDeathTest, GetElement) { +TEST(VectorDeathTest, GetElement) { Vector<int> a; a.PushBack(0); a.PushBack(1); a.PushBack(2); + const Vector<int>& b = a; - EXPECT_EQ(0, a.GetElement(0)); - EXPECT_EQ(1, a.GetElement(1)); - EXPECT_EQ(2, a.GetElement(2)); + EXPECT_EQ(0, b.GetElement(0)); + EXPECT_EQ(1, b.GetElement(1)); + EXPECT_EQ(2, b.GetElement(2)); EXPECT_DEATH_IF_SUPPORTED( - a.GetElement(3), + b.GetElement(3), "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); EXPECT_DEATH_IF_SUPPORTED( - a.GetElement(-1), + b.GetElement(-1), "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); } +// Tests the GetMutableElement accessor. +TEST(VectorDeathTest, GetMutableElement) { + Vector<int> a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + + EXPECT_EQ(0, a.GetMutableElement(0)); + EXPECT_EQ(1, a.GetMutableElement(1)); + EXPECT_EQ(2, a.GetMutableElement(2)); + + a.GetMutableElement(0) = 42; + EXPECT_EQ(42, a.GetMutableElement(0)); + EXPECT_EQ(1, a.GetMutableElement(1)); + EXPECT_EQ(2, a.GetMutableElement(2)); + + EXPECT_DEATH_IF_SUPPORTED( + a.GetMutableElement(3), + "Invalid Vector index 3: must be in range \\[0, 2\\]\\."); + EXPECT_DEATH_IF_SUPPORTED( + a.GetMutableElement(-1), + "Invalid Vector index -1: must be in range \\[0, 2\\]\\."); +} + +TEST(VectorDeathTest, Swap) { + Vector<int> a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(-1, 1), + "Invalid first swap element -1: must be in range \\[0, 2\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(3, 1), + "Invalid first swap element 3: must be in range \\[0, 2\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(1, -1), + "Invalid second swap element -1: must be in range \\[0, 2\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.Swap(1, 3), + "Invalid second swap element 3: must be in range \\[0, 2\\]"); +} + +TEST(VectorDeathTest, ShuffleRange) { + Vector<int> a; + a.PushBack(0); + a.PushBack(1); + a.PushBack(2); + testing::internal::Random random(1); + + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, -1, 1), + "Invalid shuffle range start -1: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, 4, 4), + "Invalid shuffle range start 4: must be in range \\[0, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, 3, 2), + "Invalid shuffle range finish 2: must be in range \\[3, 3\\]"); + EXPECT_DEATH_IF_SUPPORTED( + a.ShuffleRange(&random, 3, 4), + "Invalid shuffle range finish 4: must be in range \\[3, 3\\]"); +} + +class VectorShuffleTest : public Test { + protected: + static const int kVectorSize = 20; + + VectorShuffleTest() : random_(1) { + for (int i = 0; i < kVectorSize; i++) { + vector_.PushBack(i); + } + } + + static bool VectorIsCorrupt(const TestingVector& vector) { + if (kVectorSize != vector.size()) { + return true; + } + + bool found_in_vector[kVectorSize] = { false }; + for (int i = 0; i < vector.size(); i++) { + const int e = vector.GetElement(i); + if (e < 0 || e >= kVectorSize || found_in_vector[e]) { + return true; + } + found_in_vector[e] = true; + } + + // Vector size is correct, elements' range is correct, no + // duplicate elements. Therefore no corruption has occurred. + return false; + } + + static bool VectorIsNotCorrupt(const TestingVector& vector) { + return !VectorIsCorrupt(vector); + } + + static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) { + for (int i = begin; i < end; i++) { + if (i != vector.GetElement(i)) { + return true; + } + } + return false; + } + + static bool RangeIsUnshuffled( + const TestingVector& vector, int begin, int end) { + return !RangeIsShuffled(vector, begin, end); + } + + static bool VectorIsShuffled(const TestingVector& vector) { + return RangeIsShuffled(vector, 0, vector.size()); + } + + static bool VectorIsUnshuffled(const TestingVector& vector) { + return !VectorIsShuffled(vector); + } + + testing::internal::Random random_; + TestingVector vector_; +}; // class VectorShuffleTest + +const int VectorShuffleTest::kVectorSize; + +TEST_F(VectorShuffleTest, HandlesEmptyRange) { + // Tests an empty range at the beginning... + vector_.ShuffleRange(&random_, 0, 0); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...at the end... + vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and past the end. + vector_.ShuffleRange(&random_, kVectorSize, kVectorSize); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) { + // Tests a size one range at the beginning... + vector_.ShuffleRange(&random_, 0, 1); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...in the middle... + vector_.ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); + + // ...and at the end. + vector_.ShuffleRange(&random_, kVectorSize - 1, kVectorSize); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsUnshuffled, vector_); +} + +// Because we use our own random number generator and a fixed seed, +// we can guarantee that the following "random" tests will succeed. + +TEST_F(VectorShuffleTest, ShufflesEntireVector) { + vector_.Shuffle(&random_); + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_; + + // Tests the first and last elements in particular to ensure that + // there are no off-by-one problems in our shuffle algorithm. + EXPECT_NE(0, vector_.GetElement(0)); + EXPECT_NE(kVectorSize - 1, vector_.GetElement(kVectorSize - 1)); +} + +TEST_F(VectorShuffleTest, ShufflesStartOfVector) { + const int kRangeSize = kVectorSize/2; + + vector_.ShuffleRange(&random_, 0, kRangeSize); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesEndOfVector) { + const int kRangeSize = kVectorSize / 2; + vector_.ShuffleRange(&random_, kRangeSize, kVectorSize); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) { + int kRangeSize = kVectorSize/3; + vector_.ShuffleRange(&random_, kRangeSize, 2*kRangeSize); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize); + EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize); + EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize); +} + +TEST_F(VectorShuffleTest, ShufflesRepeatably) { + TestingVector vector2; + for (int i = 0; i < kVectorSize; i++) { + vector2.PushBack(i); + } + + random_.Reseed(1234); + vector_.Shuffle(&random_); + random_.Reseed(1234); + vector2.Shuffle(&random_); + + ASSERT_PRED1(VectorIsNotCorrupt, vector_); + ASSERT_PRED1(VectorIsNotCorrupt, vector2); + + for (int i = 0; i < kVectorSize; i++) { + EXPECT_EQ(vector_.GetElement(i), vector2.GetElement(i)) + << " where i is " << i; + } +} + +// Tests the size of the AssertHelper class. + +TEST(AssertHelperTest, AssertHelperIsSmall) { + // To avoid breaking clients that use lots of assertions in one + // function, we cannot grow the size of AssertHelper. + EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*)); +} + // Tests the String class. // Tests String's constructors. @@ -703,19 +1062,49 @@ TEST(StringTest, Constructors) { String s1; // We aren't using EXPECT_EQ(NULL, s1.c_str()) because comparing // pointers with NULL isn't supported on all platforms. + EXPECT_EQ(0U, s1.length()); EXPECT_TRUE(NULL == s1.c_str()); // Implicitly constructs from a C-string. String s2 = "Hi"; + EXPECT_EQ(2U, s2.length()); EXPECT_STREQ("Hi", s2.c_str()); // Constructs from a C-string and a length. String s3("hello", 3); + EXPECT_EQ(3U, s3.length()); EXPECT_STREQ("hel", s3.c_str()); - // Copy ctor. - String s4 = s3; - EXPECT_STREQ("hel", s4.c_str()); + // The empty String should be created when String is constructed with + // a NULL pointer and length 0. + EXPECT_EQ(0U, String(NULL, 0).length()); + EXPECT_FALSE(String(NULL, 0).c_str() == NULL); + + // Constructs a String that contains '\0'. + String s4("a\0bcd", 4); + EXPECT_EQ(4U, s4.length()); + EXPECT_EQ('a', s4.c_str()[0]); + EXPECT_EQ('\0', s4.c_str()[1]); + EXPECT_EQ('b', s4.c_str()[2]); + EXPECT_EQ('c', s4.c_str()[3]); + + // Copy ctor where the source is NULL. + const String null_str; + String s5 = null_str; + EXPECT_TRUE(s5.c_str() == NULL); + + // Copy ctor where the source isn't NULL. + String s6 = s3; + EXPECT_EQ(3U, s6.length()); + EXPECT_STREQ("hel", s6.c_str()); + + // Copy ctor where the source contains '\0'. + String s7 = s4; + EXPECT_EQ(4U, s7.length()); + EXPECT_EQ('a', s7.c_str()[0]); + EXPECT_EQ('\0', s7.c_str()[1]); + EXPECT_EQ('b', s7.c_str()[2]); + EXPECT_EQ('c', s7.c_str()[3]); } #if GTEST_HAS_STD_STRING @@ -724,17 +1113,22 @@ TEST(StringTest, ConvertsFromStdString) { // An empty std::string. const std::string src1(""); const String dest1 = src1; + EXPECT_EQ(0U, dest1.length()); EXPECT_STREQ("", dest1.c_str()); // A normal std::string. const std::string src2("Hi"); const String dest2 = src2; + EXPECT_EQ(2U, dest2.length()); EXPECT_STREQ("Hi", dest2.c_str()); // An std::string with an embedded NUL character. - const char src3[] = "Hello\0world."; + const char src3[] = "a\0b"; const String dest3 = std::string(src3, sizeof(src3)); - EXPECT_STREQ("Hello", dest3.c_str()); + EXPECT_EQ(sizeof(src3), dest3.length()); + EXPECT_EQ('a', dest3.c_str()[0]); + EXPECT_EQ('\0', dest3.c_str()[1]); + EXPECT_EQ('b', dest3.c_str()[2]); } TEST(StringTest, ConvertsToStdString) { @@ -747,6 +1141,11 @@ TEST(StringTest, ConvertsToStdString) { const String src2("Hi"); const std::string dest2 = src2; EXPECT_EQ("Hi", dest2); + + // A String containing a '\0'. + const String src3("x\0y", 3); + const std::string dest3 = src3; + EXPECT_EQ(std::string("x\0y", 3), dest3); } #endif // GTEST_HAS_STD_STRING @@ -757,17 +1156,22 @@ TEST(StringTest, ConvertsFromGlobalString) { // An empty ::string. const ::string src1(""); const String dest1 = src1; + EXPECT_EQ(0U, dest1.length()); EXPECT_STREQ("", dest1.c_str()); // A normal ::string. const ::string src2("Hi"); const String dest2 = src2; + EXPECT_EQ(2U, dest2.length()); EXPECT_STREQ("Hi", dest2.c_str()); // An ::string with an embedded NUL character. - const char src3[] = "Hello\0world."; + const char src3[] = "x\0y"; const String dest3 = ::string(src3, sizeof(src3)); - EXPECT_STREQ("Hello", dest3.c_str()); + EXPECT_EQ(sizeof(src3), dest3.length()); + EXPECT_EQ('x', dest3.c_str()[0]); + EXPECT_EQ('\0', dest3.c_str()[1]); + EXPECT_EQ('y', dest3.c_str()[2]); } TEST(StringTest, ConvertsToGlobalString) { @@ -780,17 +1184,14 @@ TEST(StringTest, ConvertsToGlobalString) { const String src2("Hi"); const ::string dest2 = src2; EXPECT_EQ("Hi", dest2); + + const String src3("x\0y", 3); + const ::string dest3 = src3; + EXPECT_EQ(::string("x\0y", 3), dest3); } #endif // GTEST_HAS_GLOBAL_STRING -// Tests String::ShowCString(). -TEST(StringTest, ShowCString) { - EXPECT_STREQ("(null)", String::ShowCString(NULL)); - EXPECT_STREQ("", String::ShowCString("")); - EXPECT_STREQ("foo", String::ShowCString("foo")); -} - // Tests String::ShowCStringQuoted(). TEST(StringTest, ShowCStringQuoted) { EXPECT_STREQ("(null)", @@ -801,6 +1202,53 @@ TEST(StringTest, ShowCStringQuoted) { String::ShowCStringQuoted("foo").c_str()); } +// Tests String::empty(). +TEST(StringTest, Empty) { + EXPECT_TRUE(String("").empty()); + EXPECT_FALSE(String().empty()); + EXPECT_FALSE(String(NULL).empty()); + EXPECT_FALSE(String("a").empty()); + EXPECT_FALSE(String("\0", 1).empty()); +} + +// Tests String::Compare(). +TEST(StringTest, Compare) { + // NULL vs NULL. + EXPECT_EQ(0, String().Compare(String())); + + // NULL vs non-NULL. + EXPECT_EQ(-1, String().Compare(String(""))); + + // Non-NULL vs NULL. + EXPECT_EQ(1, String("").Compare(String())); + + // The following covers non-NULL vs non-NULL. + + // "" vs "". + EXPECT_EQ(0, String("").Compare(String(""))); + + // "" vs non-"". + EXPECT_EQ(-1, String("").Compare(String("\0", 1))); + EXPECT_EQ(-1, String("").Compare(" ")); + + // Non-"" vs "". + EXPECT_EQ(1, String("a").Compare(String(""))); + + // The following covers non-"" vs non-"". + + // Same length and equal. + EXPECT_EQ(0, String("a").Compare(String("a"))); + + // Same length and different. + EXPECT_EQ(-1, String("a\0b", 3).Compare(String("a\0c", 3))); + EXPECT_EQ(1, String("b").Compare(String("a"))); + + // Different lengths. + EXPECT_EQ(-1, String("a").Compare(String("ab"))); + EXPECT_EQ(-1, String("a").Compare(String("a\0", 2))); + EXPECT_EQ(1, String("abc").Compare(String("aacd"))); +} + // Tests String::operator==(). TEST(StringTest, Equals) { const String null(NULL); @@ -818,6 +1266,9 @@ TEST(StringTest, Equals) { EXPECT_FALSE(foo == ""); // NOLINT EXPECT_FALSE(foo == "bar"); // NOLINT EXPECT_TRUE(foo == "foo"); // NOLINT + + const String bar("x\0y", 3); + EXPECT_FALSE(bar == "x"); } // Tests String::operator!=(). @@ -837,6 +1288,17 @@ TEST(StringTest, NotEquals) { EXPECT_TRUE(foo != ""); // NOLINT EXPECT_TRUE(foo != "bar"); // NOLINT EXPECT_FALSE(foo != "foo"); // NOLINT + + const String bar("x\0y", 3); + EXPECT_TRUE(bar != "x"); +} + +// Tests String::length(). +TEST(StringTest, Length) { + EXPECT_EQ(0U, String().length()); + EXPECT_EQ(0U, String("").length()); + EXPECT_EQ(2U, String("ab").length()); + EXPECT_EQ(3U, String("a\0b", 3).length()); } // Tests String::EndsWith(). @@ -900,9 +1362,17 @@ TEST(StringTest, CanBeAssignedEmpty) { TEST(StringTest, CanBeAssignedNonEmpty) { const String src("hello"); String dest; - dest = src; + EXPECT_EQ(5U, dest.length()); EXPECT_STREQ("hello", dest.c_str()); + + const String src2("x\0y", 3); + String dest2; + dest2 = src2; + EXPECT_EQ(3U, dest2.length()); + EXPECT_EQ('x', dest2.c_str()[0]); + EXPECT_EQ('\0', dest2.c_str()[1]); + EXPECT_EQ('y', dest2.c_str()[2]); } // Tests that a String can be assigned to itself. @@ -913,6 +1383,40 @@ TEST(StringTest, CanBeAssignedSelf) { EXPECT_STREQ("hello", dest.c_str()); } +// Tests streaming a String. +TEST(StringTest, Streams) { + EXPECT_EQ(StreamableToString(String()), "(null)"); + EXPECT_EQ(StreamableToString(String("")), ""); + EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b"); +} + +// Tests that String::Format() works. +TEST(StringTest, FormatWorks) { + // Normal case: the format spec is valid, the arguments match the + // spec, and the result is < 4095 characters. + EXPECT_STREQ("Hello, 42", String::Format("%s, %d", "Hello", 42).c_str()); + + // Edge case: the result is 4095 characters. + char buffer[4096]; + const size_t kSize = sizeof(buffer); + memset(buffer, 'a', kSize - 1); + buffer[kSize - 1] = '\0'; + EXPECT_STREQ(buffer, String::Format("%s", buffer).c_str()); + + // The result needs to be 4096 characters, exceeding Format()'s limit. + EXPECT_STREQ("<formatting error or buffer exceeded>", + String::Format("x%s", buffer).c_str()); + +#if GTEST_OS_LINUX + // On Linux, invalid format spec should lead to an error message. + // In other environment (e.g. MSVC on Windows), String::Format() may + // simply ignore a bad format spec, so this assertion is run on + // Linux only. + EXPECT_STREQ("<formatting error or buffer exceeded>", + String::Format("%").c_str()); +#endif +} + #if GTEST_OS_WINDOWS // Tests String::ShowWideCString(). @@ -933,7 +1437,7 @@ TEST(StringTest, ShowWideCStringQuoted) { String::ShowWideCStringQuoted(L"foo").c_str()); } -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE TEST(StringTest, AnsiAndUtf16Null) { EXPECT_EQ(NULL, String::AnsiToUtf16(NULL)); EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL)); @@ -956,7 +1460,7 @@ TEST(StringTest, AnsiAndUtf16ConvertPathChars) { EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3)); delete [] utf16; } -#endif // _WIN32_WCE +#endif // GTEST_OS_WINDOWS_MOBILE #endif // GTEST_OS_WINDOWS @@ -1221,12 +1725,12 @@ TEST(TestPartResultTest, ConstructorWorks) { message << static_cast<const char*>(testing::internal::kStackTraceMarker); message << "some unimportant stack trace"; - const TestPartResult result(TPRT_NONFATAL_FAILURE, + const TestPartResult result(TestPartResult::kNonFatalFailure, "some_file.cc", 42, message.GetString().c_str()); - EXPECT_EQ(TPRT_NONFATAL_FAILURE, result.type()); + EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type()); EXPECT_STREQ("some_file.cc", result.file_name()); EXPECT_EQ(42, result.line_number()); EXPECT_STREQ(message.GetString().c_str(), result.message()); @@ -1234,13 +1738,16 @@ TEST(TestPartResultTest, ConstructorWorks) { } TEST(TestPartResultTest, ResultAccessorsWork) { - const TestPartResult success(TPRT_SUCCESS, "file.cc", 42, "message"); + const TestPartResult success(TestPartResult::kSuccess, + "file.cc", + 42, + "message"); EXPECT_TRUE(success.passed()); EXPECT_FALSE(success.failed()); EXPECT_FALSE(success.nonfatally_failed()); EXPECT_FALSE(success.fatally_failed()); - const TestPartResult nonfatal_failure(TPRT_NONFATAL_FAILURE, + const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure, "file.cc", 42, "message"); @@ -1249,7 +1756,7 @@ TEST(TestPartResultTest, ResultAccessorsWork) { EXPECT_TRUE(nonfatal_failure.nonfatally_failed()); EXPECT_FALSE(nonfatal_failure.fatally_failed()); - const TestPartResult fatal_failure(TPRT_FATAL_FAILURE, + const TestPartResult fatal_failure(TestPartResult::kFatalFailure, "file.cc", 42, "message"); @@ -1274,10 +1781,14 @@ class TestResultTest : public Test { virtual void SetUp() { // pr1 is for success. - pr1 = new TestPartResult(TPRT_SUCCESS, "foo/bar.cc", 10, "Success!"); + pr1 = new TestPartResult(TestPartResult::kSuccess, + "foo/bar.cc", + 10, + "Success!"); // pr2 is for fatal failure. - pr2 = new TestPartResult(TPRT_FATAL_FAILURE, "foo/bar.cc", + pr2 = new TestPartResult(TestPartResult::kFatalFailure, + "foo/bar.cc", -1, // This line number means "unknown" "Failure!"); @@ -1577,7 +2088,7 @@ TEST_F(GTestFlagSaverTest, VerifyGTestFlags) { // value. If the value argument is "", unsets the environment // variable. The caller must ensure that both arguments are not NULL. static void SetEnv(const char* name, const char* value) { -#ifdef _WIN32_WCE +#if GTEST_OS_WINDOWS_MOBILE // Environment variables are not supported on Windows CE. return; #elif defined(__BORLANDC__) @@ -1595,7 +2106,6 @@ static void SetEnv(const char* name, const char* value) { added_env[name] = new String((Message() << name << "=" << value).GetString()); putenv(added_env[name]->c_str()); delete prev_env; - #elif GTEST_OS_WINDOWS // If we are on Windows proper. _putenv((Message() << name << "=" << value).GetString().c_str()); #else @@ -1604,10 +2114,10 @@ static void SetEnv(const char* name, const char* value) { } else { setenv(name, value, 1); } -#endif +#endif // GTEST_OS_WINDOWS_MOBILE } -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE // Environment variables are not supported on Windows CE. using testing::internal::Int32FromGTestEnv; @@ -1655,7 +2165,7 @@ TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321"); EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0)); } -#endif // !defined(_WIN32_WCE) +#endif // !GTEST_OS_WINDOWS_MOBILE // Tests ParseInt32Flag(). @@ -1713,7 +2223,7 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) { // Tests that Int32FromEnvOrDie() parses the value of the var or // returns the correct default. // Environment variables are not supported on Windows CE. -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123"); @@ -1721,7 +2231,7 @@ TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) { SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123"); EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333)); } -#endif // _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE // Tests that Int32FromEnvOrDie() aborts with an error message // if the variable is not an Int32. @@ -1788,7 +2298,7 @@ TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) { // Tests that sharding is enabled if total_shards > 1 and // we are not in a death test subprocess. // Environment variables are not supported on Windows CE. -#ifndef _WIN32_WCE +#if !GTEST_OS_WINDOWS_MOBILE TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { SetEnv(index_var_, "4"); SetEnv(total_var_, "22"); @@ -1805,7 +2315,7 @@ TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) { EXPECT_TRUE(ShouldShard(total_var_, index_var_, false)); EXPECT_FALSE(ShouldShard(total_var_, index_var_, true)); } -#endif // _WIN32_WCE +#endif // !GTEST_OS_WINDOWS_MOBILE // Tests that we exit in error if the sharding values are not valid. @@ -3151,9 +3661,9 @@ TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) { DoAssertNoFatalFailureOnFails(); } ASSERT_EQ(2, gtest_failures.size()); - EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(0).type()); - EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(1).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", gtest_failures.GetTestPartResult(0).message()); @@ -3168,11 +3678,11 @@ TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) { DoExpectNoFatalFailureOnFails(); } ASSERT_EQ(3, gtest_failures.size()); - EXPECT_EQ(testing::TPRT_FATAL_FAILURE, + EXPECT_EQ(TestPartResult::kFatalFailure, gtest_failures.GetTestPartResult(0).type()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(1).type()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(2).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure", gtest_failures.GetTestPartResult(0).message()); @@ -3189,9 +3699,9 @@ TEST_F(NoFatalFailureTest, MessageIsStreamable) { EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message"; } ASSERT_EQ(2, gtest_failures.size()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(0).type()); - EXPECT_EQ(testing::TPRT_NONFATAL_FAILURE, + EXPECT_EQ(TestPartResult::kNonFatalFailure, gtest_failures.GetTestPartResult(1).type()); EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo", gtest_failures.GetTestPartResult(0).message()); @@ -3651,19 +4161,19 @@ TEST(HRESULTAssertionTest, Streaming) { // Tests that the assertion macros behave like single statements. TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { - if (false) + if (AlwaysFalse()) ASSERT_TRUE(false) << "This should never be executed; " "It's a compilation test only."; - if (true) + if (AlwaysTrue()) EXPECT_FALSE(false); else ; // NOLINT - if (false) + if (AlwaysFalse()) ASSERT_LT(1, 3); - if (false) + if (AlwaysFalse()) ; // NOLINT else EXPECT_GT(3, 2) << ""; @@ -3685,26 +4195,26 @@ TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { } TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { - if (false) + if (AlwaysFalse()) EXPECT_THROW(ThrowNothing(), bool); - if (true) + if (AlwaysTrue()) EXPECT_THROW(ThrowAnInteger(), int); else ; // NOLINT - if (false) + if (AlwaysFalse()) EXPECT_NO_THROW(ThrowAnInteger()); - if (true) + if (AlwaysTrue()) EXPECT_NO_THROW(ThrowNothing()); else ; // NOLINT - if (false) + if (AlwaysFalse()) EXPECT_ANY_THROW(ThrowNothing()); - if (true) + if (AlwaysTrue()) EXPECT_ANY_THROW(ThrowAnInteger()); else ; // NOLINT @@ -3712,23 +4222,23 @@ TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { #endif // GTEST_HAS_EXCEPTIONS TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) { - if (false) + if (AlwaysFalse()) EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. " << "It's a compilation test only."; else ; // NOLINT - if (false) + if (AlwaysFalse()) ASSERT_NO_FATAL_FAILURE(FAIL()) << ""; else ; // NOLINT - if (true) + if (AlwaysTrue()) EXPECT_NO_FATAL_FAILURE(SUCCEED()); else ; // NOLINT - if (false) + if (AlwaysFalse()) ; // NOLINT else ASSERT_NO_FATAL_FAILURE(SUCCEED()); @@ -6018,3 +6528,320 @@ TEST(HasFailureTest, WorksOutsideOfTestBody2) { ClearCurrentTestPartResults(); EXPECT_TRUE(has_failure); } + +class TestListener : public EmptyTestEventListener { + public: + TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {} + TestListener(int* on_start_counter, bool* is_destroyed) + : on_start_counter_(on_start_counter), + is_destroyed_(is_destroyed) {} + + virtual ~TestListener() { + if (is_destroyed_) + *is_destroyed_ = true; + } + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + if (on_start_counter_ != NULL) + (*on_start_counter_)++; + } + + private: + int* on_start_counter_; + bool* is_destroyed_; +}; + +// Tests the constructor. +TEST(TestEventListenersTest, ConstructionWorks) { + TestEventListeners listeners; + + EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != NULL); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); +} + +// Tests that the TestEventListeners destructor deletes all the listeners it +// owns. +TEST(TestEventListenersTest, DestructionWorks) { + bool default_result_printer_is_destroyed = false; + bool default_xml_printer_is_destroyed = false; + bool extra_listener_is_destroyed = false; + TestListener* default_result_printer = new TestListener( + NULL, &default_result_printer_is_destroyed); + TestListener* default_xml_printer = new TestListener( + NULL, &default_xml_printer_is_destroyed); + TestListener* extra_listener = new TestListener( + NULL, &extra_listener_is_destroyed); + + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, + default_result_printer); + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, + default_xml_printer); + listeners.Append(extra_listener); + } + EXPECT_TRUE(default_result_printer_is_destroyed); + EXPECT_TRUE(default_xml_printer_is_destroyed); + EXPECT_TRUE(extra_listener_is_destroyed); +} + +// Tests that a listener Append'ed to a TestEventListeners list starts +// receiving events. +TEST(TestEventListenersTest, Append) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); + } + EXPECT_TRUE(is_destroyed); +} + +// Tests that listeners receive events in the order they were appended to +// the list, except for *End requests, which must be received in the reverse +// order. +class SequenceTestingListener : public EmptyTestEventListener { + public: + SequenceTestingListener(Vector<String>* vector, const char* id) + : vector_(vector), id_(id) {} + + protected: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) { + vector_->PushBack(GetEventDescription("OnTestProgramStart")); + } + + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) { + vector_->PushBack(GetEventDescription("OnTestProgramEnd")); + } + + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->PushBack(GetEventDescription("OnTestIterationStart")); + } + + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) { + vector_->PushBack(GetEventDescription("OnTestIterationEnd")); + } + + private: + String GetEventDescription(const char* method) { + Message message; + message << id_ << "." << method; + return message.GetString(); + } + + Vector<String>* vector_; + const char* const id_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener); +}; + +TEST(EventListenerTest, AppendKeepsOrder) { + Vector<String> vec; + TestEventListeners listeners; + listeners.Append(new SequenceTestingListener(&vec, "1st")); + listeners.Append(new SequenceTestingListener(&vec, "2nd")); + listeners.Append(new SequenceTestingListener(&vec, "3rd")); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + ASSERT_EQ(3, vec.size()); + EXPECT_STREQ("1st.OnTestProgramStart", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestProgramStart", vec.GetElement(1).c_str()); + EXPECT_STREQ("3rd.OnTestProgramStart", vec.GetElement(2).c_str()); + + vec.Clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd( + *UnitTest::GetInstance()); + ASSERT_EQ(3, vec.size()); + EXPECT_STREQ("3rd.OnTestProgramEnd", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestProgramEnd", vec.GetElement(1).c_str()); + EXPECT_STREQ("1st.OnTestProgramEnd", vec.GetElement(2).c_str()); + + vec.Clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3, vec.size()); + EXPECT_STREQ("1st.OnTestIterationStart", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestIterationStart", vec.GetElement(1).c_str()); + EXPECT_STREQ("3rd.OnTestIterationStart", vec.GetElement(2).c_str()); + + vec.Clear(); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd( + *UnitTest::GetInstance(), 0); + ASSERT_EQ(3, vec.size()); + EXPECT_STREQ("3rd.OnTestIterationEnd", vec.GetElement(0).c_str()); + EXPECT_STREQ("2nd.OnTestIterationEnd", vec.GetElement(1).c_str()); + EXPECT_STREQ("1st.OnTestIterationEnd", vec.GetElement(2).c_str()); +} + +// Tests that a listener removed from a TestEventListeners list stops receiving +// events and is not deleted when the list is destroyed. +TEST(TestEventListenersTest, Release) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + listeners.Append(listener); + EXPECT_EQ(listener, listeners.Release(listener)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_TRUE(listeners.Release(listener) == NULL); + } + EXPECT_EQ(0, on_start_counter); + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that no events are forwarded when event forwarding is disabled. +TEST(EventListenerTest, SuppressEventForwarding) { + int on_start_counter = 0; + TestListener* listener = new TestListener(&on_start_counter, NULL); + + TestEventListeners listeners; + listeners.Append(listener); + ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::SuppressEventForwarding(&listeners); + ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners)); + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); +} + +// Tests that events generated by Google Test are not forwarded in +// death test subprocesses. +TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) { + EXPECT_DEATH_IF_SUPPORTED({ + GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled( + *GetUnitTestImpl()->listeners())) << "expected failure";}, + "expected failure"); +} + +// Tests that a listener installed via SetDefaultResultPrinter() starts +// receiving events and is returned via default_result_printer() and that +// the previous default_result_printer is removed from the list and deleted. +TEST(EventListenerTest, default_result_printer) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_result_printer()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_result_printer with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL); + + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_result_printer listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_result_printer() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_result_printer. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} + +// Tests that a listener installed via SetDefaultXmlGenerator() starts +// receiving events and is returned via default_xml_generator() and that +// the previous default_xml_generator is removed from the list and deleted. +TEST(EventListenerTest, default_xml_generator) { + int on_start_counter = 0; + bool is_destroyed = false; + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.default_xml_generator()); + + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + + EXPECT_EQ(1, on_start_counter); + + // Replacing default_xml_generator with something else should remove it + // from the list and destroy it. + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL); + + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_TRUE(is_destroyed); + + // After broadcasting an event the counter is still the same, indicating + // the listener is not in the list anymore. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(1, on_start_counter); +} + +// Tests that the default_xml_generator listener stops receiving events +// when removed via Release and that is not owned by the list anymore. +TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) { + int on_start_counter = 0; + bool is_destroyed = false; + // Although Append passes the ownership of this object to the list, + // the following calls release it, and we need to delete it before the + // test ends. + TestListener* listener = new TestListener(&on_start_counter, &is_destroyed); + { + TestEventListeners listeners; + TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener); + + EXPECT_EQ(listener, listeners.Release(listener)); + EXPECT_TRUE(listeners.default_xml_generator() == NULL); + EXPECT_FALSE(is_destroyed); + + // Broadcasting events now should not affect default_xml_generator. + TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart( + *UnitTest::GetInstance()); + EXPECT_EQ(0, on_start_counter); + } + // Destroying the list should not affect the listener now, too. + EXPECT_FALSE(is_destroyed); + delete listener; +} diff --git a/gtest/test/gtest_xml_output_unittest.py b/gtest/test/gtest_xml_output_unittest.py index a0cd4d0..6d44929 100755 --- a/gtest/test/gtest_xml_output_unittest.py +++ b/gtest/test/gtest_xml_output_unittest.py @@ -44,6 +44,7 @@ import gtest_xml_test_utils GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_" SUPPORTS_STACK_TRACES = False @@ -53,7 +54,7 @@ else: STACK_TRACE_TEMPLATE = "" EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?> -<testsuites tests="13" failures="2" disabled="2" errors="0" time="*" name="AllTests"> +<testsuites tests="15" failures="4" disabled="2" errors="0" time="*" name="AllTests"> <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/> </testsuite> @@ -76,6 +77,20 @@ Expected: 2%(stack)s]]></failure> </testcase> <testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/> </testsuite> + <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*"> + <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest"> + <failure message="Failed
XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]></top>" type=""><![CDATA[gtest_xml_output_unittest_.cc:* +Failed +XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]><![CDATA[</top>%(stack)s]]></failure> + </testcase> + </testsuite> + <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*"> + <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest"> + <failure message="Failed
Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:* +Failed +Invalid characters in brackets []%(stack)s]]></failure> + </testcase> + </testsuite> <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*"> <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/> </testsuite> @@ -108,8 +123,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): Runs a test program that generates a non-empty XML output, and tests that the XML output is expected. """ - self._TestXmlOutput("gtest_xml_output_unittest_", - EXPECTED_NON_EMPTY_XML, 1) + self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) def testEmptyXmlOutput(self): """ @@ -142,6 +156,35 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): self.assertEquals(0, p.exit_code) self.assert_(os.path.isfile(output_file)) + def testSuppressedXmlOutput(self): + """ + Tests that no XML file is generated if the default XML listener is + shut down before RUN_ALL_TESTS is invoked. + """ + + xml_path = os.path.join(gtest_test_utils.GetTempDir(), + GTEST_PROGRAM_NAME + "out.xml") + if os.path.isfile(xml_path): + os.remove(xml_path) + + gtest_prog_path = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) + + command = [gtest_prog_path, + "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path), + "--shut_down_xml"] + p = gtest_test_utils.Subprocess(command) + if p.terminated_by_signal: + self.assert_(False, + "%s was killed by signal %d" % (gtest_prog_name, p.signal)) + else: + self.assert_(p.exited) + self.assertEquals(1, p.exit_code, + "'%s' exited with code %s, which doesn't match " + "the expected exit code %s." + % (command, p.exit_code, 1)) + + self.assert_(not os.path.isfile(xml_path)) + def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code): """ diff --git a/gtest/test/gtest_xml_output_unittest_.cc b/gtest/test/gtest_xml_output_unittest_.cc index d7ce2c6..fc07ef4 100644 --- a/gtest/test/gtest_xml_output_unittest_.cc +++ b/gtest/test/gtest_xml_output_unittest_.cc @@ -40,6 +40,10 @@ #include <gtest/gtest.h> +using ::testing::InitGoogleTest; +using ::testing::TestEventListeners; +using ::testing::UnitTest; + class SuccessfulTest : public testing::Test { }; @@ -76,6 +80,17 @@ TEST(MixedResultTest, DISABLED_test) { FAIL() << "Unexpected failure: Disabled test should not be run"; } +TEST(XmlQuotingTest, OutputsCData) { + FAIL() << "XML output: " + "<?xml encoding=\"utf-8\"><top><![CDATA[cdata text]]></top>"; +} + +// Helps to test that invalid characters produced by test code do not make +// it into the XML file. +TEST(InvalidCharactersTest, InvalidCharactersInMessage) { + FAIL() << "Invalid characters in brackets [\x1\x2]"; +} + class PropertyRecordingTest : public testing::Test { }; @@ -118,3 +133,13 @@ TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) { TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) { ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); } + +int main(int argc, char** argv) { + InitGoogleTest(&argc, argv); + + if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) { + TestEventListeners& listeners = UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_xml_generator()); + } + return RUN_ALL_TESTS(); +} diff --git a/gtest/test/gtest_xml_test_utils.py b/gtest/test/gtest_xml_test_utils.py index 1811c40..c83c3b7 100755 --- a/gtest/test/gtest_xml_test_utils.py +++ b/gtest/test/gtest_xml_test_utils.py @@ -77,19 +77,29 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): expected_attributes = expected_node.attributes actual_attributes = actual_node .attributes - self.assertEquals(expected_attributes.length, actual_attributes.length) + self.assertEquals( + expected_attributes.length, actual_attributes.length, + "attribute numbers differ in element " + actual_node.tagName) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) - self.assert_(actual_attr is not None) - self.assertEquals(expected_attr.value, actual_attr.value) + self.assert_( + actual_attr is not None, + "expected attribute %s not found in element %s" % + (expected_attr.name, actual_node.tagName)) + self.assertEquals(expected_attr.value, actual_attr.value, + " values of attribute %s in element %s differ" % + (expected_attr.name, actual_node.tagName)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) - self.assertEquals(len(expected_children), len(actual_children)) + self.assertEquals( + len(expected_children), len(actual_children), + "number of child elements differ in element " + actual_node.tagName) for child_id, child in expected_children.iteritems(): self.assert_(child_id in actual_children, - '<%s> is not in <%s>' % (child_id, actual_children)) + '<%s> is not in <%s> (in element %s)' % + (child_id, actual_children, actual_node.tagName)) self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { @@ -103,14 +113,13 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): """ Fetches all of the child nodes of element, a DOM Element object. Returns them as the values of a dictionary keyed by the IDs of the - children. For <testsuites>, <testsuite> and <testcase> elements, - the ID is the value of their "name" attribute; for <failure> - elements, it is the value of the "message" attribute; for CDATA - section node, it is "detail". An exception is raised if any - element other than the above four is encountered, if two child - elements with the same identifying attributes are encountered, or - if any other type of node is encountered, other than Text nodes - containing only whitespace. + children. For <testsuites>, <testsuite> and <testcase> elements, the ID + is the value of their "name" attribute; for <failure> elements, it is + the value of the "message" attribute; CDATA sections and non-whitespace + text nodes are concatenated into a single CDATA section with ID + "detail". An exception is raised if any element other than the above + four is encountered, if two child elements with the same identifying + attributes are encountered, or if any other type of node is encountered. """ children = {} @@ -121,11 +130,14 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): childID = child.getAttribute(self.identifying_attribute[child.tagName]) self.assert_(childID not in children) children[childID] = child - elif child.nodeType == Node.TEXT_NODE: - self.assert_(child.nodeValue.isspace()) - elif child.nodeType == Node.CDATA_SECTION_NODE: - self.assert_("detail" not in children) - children["detail"] = child + elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: + if "detail" not in children: + if (child.nodeType == Node.CDATA_SECTION_NODE or + not child.nodeValue.isspace()): + children["detail"] = child.ownerDocument.createCDATASection( + child.nodeValue) + else: + children["detail"].nodeValue += child.nodeValue else: self.fail("Encountered unexpected node type %d" % child.nodeType) return children diff --git a/gtest/xcode/Config/FrameworkTarget.xcconfig b/gtest/xcode/Config/FrameworkTarget.xcconfig index 3deadcd..357b1c8 100644 --- a/gtest/xcode/Config/FrameworkTarget.xcconfig +++ b/gtest/xcode/Config/FrameworkTarget.xcconfig @@ -13,5 +13,5 @@ GCC_DYNAMIC_NO_PIC = NO // Dynamic libs should not have their external symbols stripped. STRIP_STYLE = non-global -// Installation Directory -INSTALL_PATH = @loader_path/../Frameworks +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/gtest/xcode/Config/InternalPythonTestTarget.xcconfig b/gtest/xcode/Config/InternalPythonTestTarget.xcconfig deleted file mode 100644 index e004445..0000000 --- a/gtest/xcode/Config/InternalPythonTestTarget.xcconfig +++ /dev/null @@ -1,8 +0,0 @@ -// -// InternalPythonTestTarget.xcconfig -// -// These are Test target settings for the gtest framework and examples. It -// is set in the "Based On:" dropdown in the "Target" info dialog. - -PRODUCT_NAME = $(TARGET_NAME)_ -HEADER_SEARCH_PATHS = ../ ../include diff --git a/gtest/xcode/Config/InternalTestTarget.xcconfig b/gtest/xcode/Config/InternalTestTarget.xcconfig deleted file mode 100644 index c50fd9c..0000000 --- a/gtest/xcode/Config/InternalTestTarget.xcconfig +++ /dev/null @@ -1,8 +0,0 @@ -// -// InternalTestTarget.xcconfig -// -// These are Test target settings for the gtest framework and examples. It -// is set in the "Based On:" dropdown in the "Target" info dialog. - -PRODUCT_NAME = $(TARGET_NAME) -HEADER_SEARCH_PATHS = ../ ../include diff --git a/gtest/xcode/Config/StaticLibraryTarget.xcconfig b/gtest/xcode/Config/StaticLibraryTarget.xcconfig new file mode 100644 index 0000000..3922fa5 --- /dev/null +++ b/gtest/xcode/Config/StaticLibraryTarget.xcconfig @@ -0,0 +1,18 @@ +// +// StaticLibraryTarget.xcconfig +// +// These are static library target settings for libgtest.a. It +// is set in the "Based On:" dropdown in the "Target" info dialog. +// This file is based on the Xcode Configuration files in: +// http://code.google.com/p/google-toolbox-for-mac/ +// + +// Static libs can be included in bundles so make them position independent +GCC_DYNAMIC_NO_PIC = NO + +// Static libs should not have their internal globals or external symbols +// stripped. +STRIP_STYLE = debugging + +// Let the user install by specifying the $DSTROOT with xcodebuild +SKIP_INSTALL = NO diff --git a/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj index 243b149..8244910 100644 --- a/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj +++ b/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 42; objects = { /* Begin PBXBuildFile section */ @@ -11,7 +11,8 @@ 3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; }; 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; }; - 3B7F0C8D0E567CC5009CA236 /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BA867DC0E561B7C00326077 /* gtest.framework */; }; + 408BEC281046D72200DEF522 /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 408BEC271046D72200DEF522 /* gtest.framework */; }; + 408BEC431046D7B300DEF522 /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 408BEC421046D7B300DEF522 /* libgtest_main.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -29,7 +30,8 @@ 3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = "<group>"; }; 3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = "<group>"; }; 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = "<group>"; }; - 3BA867DC0E561B7C00326077 /* gtest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = gtest.framework; path = ../../build/Debug/gtest.framework; sourceTree = "<group>"; }; + 408BEC271046D72200DEF522 /* gtest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = gtest.framework; path = /Library/Frameworks/gtest.framework; sourceTree = "<absolute>"; }; + 408BEC421046D7B300DEF522 /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /Library/Frameworks/gtest.framework/Versions/A/Resources/libgtest_main.a; sourceTree = "<absolute>"; }; 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; 8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -40,7 +42,8 @@ buildActionMask = 2147483647; files = ( 3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */, - 3B7F0C8D0E567CC5009CA236 /* gtest.framework in Frameworks */, + 408BEC281046D72200DEF522 /* gtest.framework in Frameworks */, + 408BEC431046D7B300DEF522 /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -78,7 +81,8 @@ 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( - 3BA867DC0E561B7C00326077 /* gtest.framework */, + 408BEC421046D7B300DEF522 /* libgtest_main.a */, + 408BEC271046D72200DEF522 /* gtest.framework */, ); name = "External Frameworks and Libraries"; sourceTree = "<group>"; @@ -165,7 +169,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 0867D691FE84028FC02AAC07 /* gTestExample */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; @@ -229,12 +233,6 @@ 3B07BDEC0E3F3F9F00647869 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/externals/googletest/xcode/build/Debug\"", - "\"$(SRCROOT)/../../build/Debug\"", - ); - INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = WidgetFrameworkTest; }; name = Debug; @@ -242,12 +240,6 @@ 3B07BDED0E3F3F9F00647869 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/externals/googletest/xcode/build/Debug\"", - "\"$(SRCROOT)/../../build/Debug\"", - ); - INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = WidgetFrameworkTest; }; name = Release; @@ -260,10 +252,7 @@ FRAMEWORK_VERSION = A; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@loader_path/../Frameworks"; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; PRODUCT_NAME = Widget; - WRAPPER_EXTENSION = framework; }; name = Debug; }; @@ -275,27 +264,23 @@ FRAMEWORK_VERSION = A; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@loader_path/../Frameworks"; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; PRODUCT_NAME = Widget; - WRAPPER_EXTENSION = framework; }; name = Release; }; 4FADC24708B4156D00ABE55E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx10.5; + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Debug; }; 4FADC24808B4156D00ABE55E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - SDKROOT = macosx10.5; + GCC_VERSION = 4.0; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; name = Release; }; diff --git a/gtest/xcode/Scripts/runtests.sh b/gtest/xcode/Scripts/runtests.sh index 168da48..9d23a77 100644 --- a/gtest/xcode/Scripts/runtests.sh +++ b/gtest/xcode/Scripts/runtests.sh @@ -1,49 +1,16 @@ #!/bin/bash -# Executes the samples and tests for the Google Test Framework +# Executes the samples and tests for the Google Test Framework. -# Help the dynamic linker find the path to the framework +# Help the dynamic linker find the path to the libraries. export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR +export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR -# Create an array of test executables -test_executables=("$BUILT_PRODUCTS_DIR/sample1_unittest" - "$BUILT_PRODUCTS_DIR/sample2_unittest" - "$BUILT_PRODUCTS_DIR/sample3_unittest" - "$BUILT_PRODUCTS_DIR/sample4_unittest" - "$BUILT_PRODUCTS_DIR/sample5_unittest" - "$BUILT_PRODUCTS_DIR/sample6_unittest" - "$BUILT_PRODUCTS_DIR/sample7_unittest" - "$BUILT_PRODUCTS_DIR/sample8_unittest" - - "$BUILT_PRODUCTS_DIR/gtest-death-test_test" - "$BUILT_PRODUCTS_DIR/gtest_environment_test" - "$BUILT_PRODUCTS_DIR/gtest-filepath_test" - "$BUILT_PRODUCTS_DIR/gtest-linked_ptr_test" - "$BUILT_PRODUCTS_DIR/gtest_main_unittest" - "$BUILT_PRODUCTS_DIR/gtest-message_test" - "$BUILT_PRODUCTS_DIR/gtest_no_test_unittest" - "$BUILT_PRODUCTS_DIR/gtest-options_test" - "$BUILT_PRODUCTS_DIR/gtest-param-test_test" - "$BUILT_PRODUCTS_DIR/gtest-port_test" - "$BUILT_PRODUCTS_DIR/gtest_pred_impl_unittest" - "$BUILT_PRODUCTS_DIR/gtest_prod_test" - "$BUILT_PRODUCTS_DIR/gtest_repeat_test" - "$BUILT_PRODUCTS_DIR/gtest_sole_header_test" - "$BUILT_PRODUCTS_DIR/gtest_stress_test" - "$BUILT_PRODUCTS_DIR/gtest_test_part_test" - "$BUILT_PRODUCTS_DIR/gtest-typed-test_test" +# Create some executables. +test_executables=("$BUILT_PRODUCTS_DIR/gtest_unittest-framework" "$BUILT_PRODUCTS_DIR/gtest_unittest" - - "$BUILT_PRODUCTS_DIR/gtest_break_on_failure_unittest.py" - "$BUILT_PRODUCTS_DIR/gtest_color_test.py" - "$BUILT_PRODUCTS_DIR/gtest_env_var_test.py" - "$BUILT_PRODUCTS_DIR/gtest_filter_unittest.py" - "$BUILT_PRODUCTS_DIR/gtest_list_tests_unittest.py" - "$BUILT_PRODUCTS_DIR/gtest_output_test.py" - "$BUILT_PRODUCTS_DIR/gtest_xml_outfiles_test.py" - "$BUILT_PRODUCTS_DIR/gtest_xml_output_unittest.py" - "$BUILT_PRODUCTS_DIR/gtest_uninitialized_test.py" -) + "$BUILT_PRODUCTS_DIR/sample1_unittest-framework" + "$BUILT_PRODUCTS_DIR/sample1_unittest-static") # Now execute each one in turn keeping track of how many succeeded and failed. succeeded=0 @@ -60,7 +27,7 @@ for test in ${test_executables[*]}; do fi done -# Report the successes and failures to the console +# Report the successes and failures to the console. echo "Tests complete with $succeeded successes and $failed failures." if [ $failed -ne 0 ]; then echo "The following tests failed:" diff --git a/gtest/xcode/gtest.xcodeproj/project.pbxproj b/gtest/xcode/gtest.xcodeproj/project.pbxproj index 2d55395..4234e72 100644 --- a/gtest/xcode/gtest.xcodeproj/project.pbxproj +++ b/gtest/xcode/gtest.xcodeproj/project.pbxproj @@ -14,70 +14,14 @@ 3B238F5E0E828B5400846E11 /* ShellScript */, ); dependencies = ( - 3B238F630E828B6100846E11 /* PBXTargetDependency */, - 3B238F650E828B6100846E11 /* PBXTargetDependency */, - 3B238F670E828B6100846E11 /* PBXTargetDependency */, - 3B238F690E828B6100846E11 /* PBXTargetDependency */, - 3B238F6B0E828B6100846E11 /* PBXTargetDependency */, - 3B238F6D0E828B6100846E11 /* PBXTargetDependency */, - 4539C94C0EC2823500A70F4C /* PBXTargetDependency */, - 4539C94A0EC2823500A70F4C /* PBXTargetDependency */, - 3B238F6F0E828B7100846E11 /* PBXTargetDependency */, - 3B238F810E828B7100846E11 /* PBXTargetDependency */, - 3B238F710E828B7100846E11 /* PBXTargetDependency */, - 4539C9B10EC284C300A70F4C /* PBXTargetDependency */, - 3B238F870E828B7100846E11 /* PBXTargetDependency */, - 3B238F730E828B7100846E11 /* PBXTargetDependency */, - 3B238F8B0E828B7100846E11 /* PBXTargetDependency */, - 3B238F750E828B7100846E11 /* PBXTargetDependency */, - 4539C95F0EC2833100A70F4C /* PBXTargetDependency */, - 4539C9B30EC284C300A70F4C /* PBXTargetDependency */, - 3B238F8F0E828B7100846E11 /* PBXTargetDependency */, - 3B238F910E828B7100846E11 /* PBXTargetDependency */, - 3B238F930E828B7100846E11 /* PBXTargetDependency */, - 22C44F370E9EB800004F2913 /* PBXTargetDependency */, - 3B238F950E828B7100846E11 /* PBXTargetDependency */, - 22C44F390E9EB808004F2913 /* PBXTargetDependency */, - 3B238F790E828B7100846E11 /* PBXTargetDependency */, - 3B238F990E828B7100846E11 /* PBXTargetDependency */, - 409A76D00ED73CA300E08B81 /* PBXTargetDependency */, - 409A76D20ED73CA300E08B81 /* PBXTargetDependency */, - 409A76D40ED73CA300E08B81 /* PBXTargetDependency */, - 409A76D60ED73CA300E08B81 /* PBXTargetDependency */, - 409A76D80ED73CA300E08B81 /* PBXTargetDependency */, - 409A76DA0ED73CA300E08B81 /* PBXTargetDependency */, - 40538A450ED71D2200AF209A /* PBXTargetDependency */, - 409A76DC0ED73CA300E08B81 /* PBXTargetDependency */, - 409A76DE0ED73CA300E08B81 /* PBXTargetDependency */, + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */, + 40C849F7101A43440083642A /* PBXTargetDependency */, + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */, + 40C849F9101A43490083642A /* PBXTargetDependency */, ); name = Check; productName = Check; }; - 40538A0A0ED71AF200AF209A /* gtest_xml_outfiles_test */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 40538A110ED71AF200AF209A /* Build configuration list for PBXAggregateTarget "gtest_xml_outfiles_test" */; - buildPhases = ( - 40538A0F0ED71AF200AF209A /* CopyFiles */, - ); - dependencies = ( - 40538A0B0ED71AF200AF209A /* PBXTargetDependency */, - 40538A150ED71B1900AF209A /* PBXTargetDependency */, - 40538A170ED71B1B00AF209A /* PBXTargetDependency */, - ); - name = gtest_xml_outfiles_test; - productName = gtest_output_test; - }; - 408454310E96D39000AC66C2 /* Setup Python */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 408454340E96D3D400AC66C2 /* Build configuration list for PBXAggregateTarget "Setup Python" */; - buildPhases = ( - 408454300E96D39000AC66C2 /* CopyFiles */, - ); - dependencies = ( - ); - name = "Setup Python"; - productName = "Setup Python"; - }; 40C44ADC0E3798F4008FCC51 /* Version Info */ = { isa = PBXAggregateTarget; buildConfigurationList = 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */; @@ -93,35 +37,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ - 222ECCA60E9EB47B00BEED94 /* gtest-test-part_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C0E0E7FE13C00846E11 /* gtest-test-part_test.cc */; }; - 224A12A00E9EAD8F00BD17FD /* gtest-test-part.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A129F0E9EAD8F00BD17FD /* gtest-test-part.cc */; }; 224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */ = {isa = PBXBuildFile; fileRef = 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 22A865FD0E70A35700F7AE6E /* gtest-typed-test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 22A865FC0E70A35700F7AE6E /* gtest-typed-test.cc */; }; - 22A866190E70A41000F7AE6E /* sample6_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 22A866180E70A41000F7AE6E /* sample6_unittest.cc */; }; - 3B238D1D0E8283EA00846E11 /* gtest-death-test_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF10E7FE13B00846E11 /* gtest-death-test_test.cc */; }; - 3B238D640E8285C500846E11 /* gtest-filepath_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF20E7FE13B00846E11 /* gtest-filepath_test.cc */; }; - 3B238D6E0E82860A00846E11 /* gtest-message_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF30E7FE13B00846E11 /* gtest-message_test.cc */; }; - 3B238D910E8286B800846E11 /* gtest-options_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF40E7FE13B00846E11 /* gtest-options_test.cc */; }; - 3B238F450E828AC300846E11 /* gtest-typed-test_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF60E7FE13B00846E11 /* gtest-typed-test_test.cc */; }; - 3B238F460E828AC800846E11 /* gtest_break_on_failure_unittest_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF90E7FE13B00846E11 /* gtest_break_on_failure_unittest_.cc */; }; - 3B238F470E828ACF00846E11 /* gtest_color_test_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BFB0E7FE13B00846E11 /* gtest_color_test_.cc */; }; - 3B238F480E828AD500846E11 /* gtest_env_var_test_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BFD0E7FE13B00846E11 /* gtest_env_var_test_.cc */; }; - 3B238F490E828ADA00846E11 /* gtest_environment_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BFE0E7FE13B00846E11 /* gtest_environment_test.cc */; }; - 3B238F4A0E828ADF00846E11 /* gtest_filter_unittest_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C000E7FE13B00846E11 /* gtest_filter_unittest_.cc */; }; - 3B238F4B0E828AE700846E11 /* gtest_list_tests_unittest_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C020E7FE13B00846E11 /* gtest_list_tests_unittest_.cc */; }; - 3B238F4C0E828AEB00846E11 /* gtest_main_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C030E7FE13B00846E11 /* gtest_main_unittest.cc */; }; - 3B238F4D0E828AF000846E11 /* gtest_nc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C040E7FE13B00846E11 /* gtest_nc.cc */; }; - 3B238F4E0E828AF400846E11 /* gtest_no_test_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C060E7FE13B00846E11 /* gtest_no_test_unittest.cc */; }; - 3B238F4F0E828AFB00846E11 /* gtest_output_test_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C080E7FE13B00846E11 /* gtest_output_test_.cc */; }; - 3B238F500E828B0000846E11 /* gtest_pred_impl_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C0B0E7FE13B00846E11 /* gtest_pred_impl_unittest.cc */; }; - 3B238F510E828B0400846E11 /* gtest_prod_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C0C0E7FE13C00846E11 /* gtest_prod_test.cc */; }; - 3B238F520E828B0800846E11 /* gtest_repeat_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C0D0E7FE13C00846E11 /* gtest_repeat_test.cc */; }; - 3B238F540E828B1700846E11 /* gtest_uninitialized_test_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C110E7FE13C00846E11 /* gtest_uninitialized_test_.cc */; }; - 3B238F550E828B1F00846E11 /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; - 3B238F560E828B2400846E11 /* gtest_xml_outfile1_test_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C130E7FE13C00846E11 /* gtest_xml_outfile1_test_.cc */; }; - 3B238F570E828B2700846E11 /* gtest_xml_outfile2_test_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C140E7FE13C00846E11 /* gtest_xml_outfile2_test_.cc */; }; - 3B238F580E828B2C00846E11 /* gtest_xml_output_unittest_.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C170E7FE13C00846E11 /* gtest_xml_output_unittest_.cc */; }; - 3B238FF90E828C7E00846E11 /* production.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C190E7FE13C00846E11 /* production.cc */; }; 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */; }; 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -131,11 +47,6 @@ 4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883E00E2F799B00CF7658 /* gtest_prod.h */; settings = {ATTRIBUTES = (Public, ); }; }; 404884500E2F799B00CF7658 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 404883F60E2F799B00CF7658 /* README */; }; - 4048845F0E2F799B00CF7658 /* gtest-death-test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404884080E2F799B00CF7658 /* gtest-death-test.cc */; }; - 404884600E2F799B00CF7658 /* gtest-filepath.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404884090E2F799B00CF7658 /* gtest-filepath.cc */; }; - 404884620E2F799B00CF7658 /* gtest-port.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840B0E2F799B00CF7658 /* gtest-port.cc */; }; - 404884630E2F799B00CF7658 /* gtest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840C0E2F799B00CF7658 /* gtest.cc */; }; - 404884640E2F799B00CF7658 /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; }; 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */; }; 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E30E2F799B00CF7658 /* gtest-filepath.h */; }; 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E40E2F799B00CF7658 /* gtest-internal.h */; }; @@ -144,591 +55,52 @@ 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; }; 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; }; 404884AE0E2F7CD900CF7658 /* COPYING in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* COPYING */; }; - 404885990E2F816100CF7658 /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404883F80E2F799B00CF7658 /* sample1.cc */; }; - 4048859B0E2F816100CF7658 /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404883FA0E2F799B00CF7658 /* sample1_unittest.cc */; }; - 404885CF0E2F82F000CF7658 /* sample2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404883FB0E2F799B00CF7658 /* sample2.cc */; }; - 404885D00E2F82F000CF7658 /* sample2_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404883FD0E2F799B00CF7658 /* sample2_unittest.cc */; }; - 404886050E2F83DF00CF7658 /* sample3_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404883FF0E2F799B00CF7658 /* sample3_unittest.cc */; }; - 404886080E2F840300CF7658 /* sample4.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404884000E2F799B00CF7658 /* sample4.cc */; }; - 404886090E2F840300CF7658 /* sample4_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404884020E2F799B00CF7658 /* sample4_unittest.cc */; }; - 4048860C0E2F840E00CF7658 /* sample5_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404884030E2F799B00CF7658 /* sample5_unittest.cc */; }; - 404886140E2F849100CF7658 /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 404883F80E2F799B00CF7658 /* sample1.cc */; }; - 40538A180ED71B2E00AF209A /* gtest_xml_outfiles_test.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C150E7FE13C00846E11 /* gtest_xml_outfiles_test.py */; }; - 4060FDBF0ED5C5C6008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC00ED5C5C7008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC10ED5C5C7008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC20ED5C5C8008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC30ED5C5C8008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC40ED5C5C9008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC50ED5C5CA008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC60ED5C5CB008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC70ED5C5CB008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC80ED5C5CC008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDC90ED5C5CC008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDCA0ED5C5CD008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDCB0ED5C5CE008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDCC0ED5C5CF008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDCD0ED5C5D0008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDCE0ED5C5D0008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDCF0ED5C5D1008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDD00ED5C5D2008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDD10ED5C5D3008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDD20ED5C5D6008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDD90ED5C5ED008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDDA0ED5C5EE008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDDB0ED5C5EF008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDDC0ED5C5EF008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDDD0ED5C5F1008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDDE0ED5C5F1008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDDF0ED5C5F2008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE00ED5C5F3008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE10ED5C5F3008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE20ED5C5F4008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE30ED5C5F5008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE40ED5C5F6008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE50ED5C5F9008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE60ED5C5F9008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE70ED5C5FA008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE80ED5C5FB008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 4060FDE90ED5C5FB008BAC1E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; - 408454350E96D3F600AC66C2 /* gtest_test_utils.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C0F0E7FE13C00846E11 /* gtest_test_utils.py */; }; - 4084548A0E96DD8200AC66C2 /* gtest_nc_test.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C050E7FE13B00846E11 /* gtest_nc_test.py */; }; - 4084548F0E97066B00AC66C2 /* gtest_xml_test_utils.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C180E7FE13C00846E11 /* gtest_xml_test_utils.py */; }; - 408454BC0E97098200AC66C2 /* gtest-typed-test2_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF50E7FE13B00846E11 /* gtest-typed-test2_test.cc */; }; - 409A76910ED73AF200E08B81 /* gtest_uninitialized_test.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C100E7FE13C00846E11 /* gtest_uninitialized_test.py */; }; - 409A76940ED73B0500E08B81 /* gtest_xml_output_unittest.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C160E7FE13C00846E11 /* gtest_xml_output_unittest.py */; }; - 409A76970ED73B2500E08B81 /* gtest_output_test.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C070E7FE13B00846E11 /* gtest_output_test.py */; }; - 409A76980ED73B2500E08B81 /* gtest_output_test_golden_lin.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C090E7FE13B00846E11 /* gtest_output_test_golden_lin.txt */; }; - 409A769B0ED73B2E00E08B81 /* gtest_list_tests_unittest.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238C010E7FE13B00846E11 /* gtest_list_tests_unittest.py */; }; - 409A769E0ED73B3800E08B81 /* gtest_filter_unittest.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238BFF0E7FE13B00846E11 /* gtest_filter_unittest.py */; }; - 409A76A10ED73B4600E08B81 /* gtest_env_var_test.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238BFC0E7FE13B00846E11 /* gtest_env_var_test.py */; }; - 409A76A20ED73B4D00E08B81 /* gtest_color_test.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238BFA0E7FE13B00846E11 /* gtest_color_test.py */; }; - 409A76A30ED73B5500E08B81 /* gtest_break_on_failure_unittest.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3B238BF80E7FE13B00846E11 /* gtest_break_on_failure_unittest.py */; }; - 40D2095B0E9FFBE500191629 /* gtest_sole_header_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 40D209590E9FFBAA00191629 /* gtest_sole_header_test.cc */; }; - 40D2095C0E9FFC0700191629 /* gtest_stress_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 40D2095A0E9FFBAA00191629 /* gtest_stress_test.cc */; }; - 4539C91E0EC2800600A70F4C /* sample7_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C91D0EC2800600A70F4C /* sample7_unittest.cc */; }; - 4539C9200EC2801E00A70F4C /* sample8_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C91F0EC2801E00A70F4C /* sample8_unittest.cc */; }; + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; }; + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C848FF101A21150083642A /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; }; + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; }; + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84978101A36540083642A /* libgtest_main.a in Resources */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; }; + 40C84982101A36850083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C8498F101A36A60083642A /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; }; + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; }; + 40C84992101A36A60083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; }; + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; }; + 40C849A2101A37050083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; + 40C849A4101A37150083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; }; 4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; }; 4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; }; 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; }; - 4539C95C0EC2830E00A70F4C /* gtest-param-test2_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C95A0EC2830E00A70F4C /* gtest-param-test2_test.cc */; }; - 4539C95D0EC2830E00A70F4C /* gtest-param-test_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C95B0EC2830E00A70F4C /* gtest-param-test_test.cc */; }; - 4539C9A10EC283E400A70F4C /* gtest-port_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C9A00EC283E400A70F4C /* gtest-port_test.cc */; }; - 4539C9AF0EC2843000A70F4C /* gtest-linked_ptr_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C9AE0EC2843000A70F4C /* gtest-linked_ptr_test.cc */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 222ECC910E9EB33A00BEED94 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 222ECCA40E9EB47B00BEED94 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 22A866030E70A39900F7AE6E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 22C44F360E9EB800004F2913 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 222ECC8F0E9EB33A00BEED94; - remoteInfo = gtest_sole_header_test; - }; - 22C44F380E9EB808004F2913 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 222ECCA20E9EB47B00BEED94; - remoteInfo = gtest_test_part_test; - }; - 3B238C980E81B92000846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238D540E82855F00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238D700E82862D00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238D7E0E82869400846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E110E82887E00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E1C0E82888500846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E290E82888800846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E380E82889000846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E430E82889500846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E500E82889800846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E5D0E82889B00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E7C0E82894300846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E870E82894800846E11 /* PBXContainerItemProxy */ = { + 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238E940E82894A00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238EA10E82894D00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238EAE0E82894F00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238EC50E8289C100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238ED00E8289C300846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238EDD0E8289C700846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238EE80E8289C900846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238EF50E8289CE00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238F0C0E828A3800846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238F170E828A3B00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238F240E828A3D00846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 3B238F620E828B6100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 404885920E2F814C00CF7658; - remoteInfo = sample1; - }; - 3B238F640E828B6100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 404885B00E2F82BA00CF7658; - remoteInfo = sample2; - }; - 3B238F660E828B6100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 404885D40E2F832A00CF7658; - remoteInfo = sample3; - }; - 3B238F680E828B6100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 404885E10E2F833000CF7658; - remoteInfo = sample4; - }; - 3B238F6A0E828B6100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 404885EE0E2F833400CF7658; - remoteInfo = sample5; - }; - 3B238F6C0E828B6100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 22A866010E70A39900F7AE6E; - remoteInfo = sample6; - }; - 3B238F6E0E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238C660E81B8B500846E11; - remoteInfo = "gtest-death-test_test"; - }; - 3B238F700E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238D520E82855F00846E11; - remoteInfo = "gtest-filepath_test"; - }; - 3B238F720E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238D690E8285DA00846E11; - remoteInfo = "gtest-message_test"; - }; - 3B238F740E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238D790E82868F00846E11; - remoteInfo = "gtest-options_test"; - }; - 3B238F780E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E0F0E82887E00846E11; - remoteInfo = "gtest-typed-test_test"; - }; - 3B238F800E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E410E82889500846E11; - remoteInfo = gtest_enviroment_test; - }; - 3B238F860E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E7A0E82894300846E11; - remoteInfo = gtest_main_unittest; - }; - 3B238F8A0E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E920E82894A00846E11; - remoteInfo = gtest_no_test_unittest; - }; - 3B238F8E0E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238EAC0E82894F00846E11; - remoteInfo = gtest_pred_impl_unittest; - }; - 3B238F900E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238EC30E8289C100846E11; - remoteInfo = gtest_prod_test; - }; - 3B238F920E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238ECE0E8289C300846E11; - remoteInfo = gtest_repeat_test; - }; - 3B238F940E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238EDB0E8289C700846E11; - remoteInfo = gtest_stress_test; - }; - 3B238F980E828B7100846E11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238EF30E8289CE00846E11; + remoteGlobalIDString = 40899F420FFA7184000B29AE; remoteInfo = gtest_unittest; }; - 404885A70E2F824900CF7658 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 404885B20E2F82BA00CF7658 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 404885D60E2F832A00CF7658 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 404885E30E2F833000CF7658 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 404885F00E2F833400CF7658 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; - }; - 40538A0C0ED71AF200AF209A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2; - remoteInfo = "Setup Python"; - }; - 40538A140ED71B1900AF209A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238F0A0E828A3800846E11; - remoteInfo = gtest_xml_outfile1_test_; - }; - 40538A160ED71B1B00AF209A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238F150E828A3B00846E11; - remoteInfo = gtest_xml_outfile2_test_; - }; - 40538A440ED71D2200AF209A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 40538A0A0ED71AF200AF209A; - remoteInfo = gtest_xml_outfiles_test; - }; - 4084546C0E96D70C00AC66C2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2; - remoteInfo = "Setup Python"; - }; - 409A76530ED7393100E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2 /* Setup Python */; - remoteInfo = "Setup Python"; - }; - 409A76570ED7393800E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2 /* Setup Python */; - remoteInfo = "Setup Python"; - }; - 409A765B0ED7393D00E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2 /* Setup Python */; - remoteInfo = "Setup Python"; - }; - 409A765F0ED7394200E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2 /* Setup Python */; - remoteInfo = "Setup Python"; - }; - 409A76630ED7394500E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2 /* Setup Python */; - remoteInfo = "Setup Python"; - }; - 409A766F0ED7395000E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2 /* Setup Python */; - remoteInfo = "Setup Python"; - }; - 409A76730ED7395400E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 408454310E96D39000AC66C2 /* Setup Python */; - remoteInfo = "Setup Python"; - }; - 409A76CF0ED73CA300E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E1A0E82888500846E11 /* gtest_break_on_failure_unittest */; - remoteInfo = gtest_break_on_failure_unittest; - }; - 409A76D10ED73CA300E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E270E82888800846E11 /* gtest_color_test */; - remoteInfo = gtest_color_test; - }; - 409A76D30ED73CA300E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E360E82889000846E11 /* gtest_env_var_test */; - remoteInfo = gtest_env_var_test; - }; - 409A76D50ED73CA300E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E4E0E82889800846E11 /* gtest_filter_unittest */; - remoteInfo = gtest_filter_unittest; - }; - 409A76D70ED73CA300E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E5B0E82889B00846E11 /* gtest_list_tests_unittest */; - remoteInfo = gtest_list_tests_unittest; - }; - 409A76D90ED73CA300E08B81 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3B238E9F0E82894D00846E11 /* gtest_output_test */; - remoteInfo = gtest_output_test; - }; - 409A76DB0ED73CA300E08B81 /* PBXContainerItemProxy */ = { + 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 3B238F220E828A3D00846E11 /* gtest_xml_output_unittest */; - remoteInfo = gtest_xml_output_unittest; + remoteGlobalIDString = 4089A0120FFACEFC000B29AE; + remoteInfo = sample1_unittest; }; - 409A76DD0ED73CA300E08B81 /* PBXContainerItemProxy */ = { + 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 3B238EE60E8289C900846E11 /* gtest_uninitialized_test */; - remoteInfo = gtest_uninitialized_test; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; }; 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -737,75 +109,68 @@ remoteGlobalIDString = 40C44ADC0E3798F4008FCC51; remoteInfo = Version.h; }; - 4539C9070EC27FBC00A70F4C /* PBXContainerItemProxy */ = { + 40C8497C101A36850083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; }; - 4539C9130EC27FC000A70F4C /* PBXContainerItemProxy */ = { + 40C8497E101A36850083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; }; - 4539C9490EC2823500A70F4C /* PBXContainerItemProxy */ = { + 40C8498B101A36A60083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4539C9110EC27FC000A70F4C; - remoteInfo = sample8_unittest; + remoteGlobalIDString = 40C848F9101A209C0083642A; + remoteInfo = "gtest-static"; }; - 4539C94B0EC2823500A70F4C /* PBXContainerItemProxy */ = { + 40C8498D101A36A60083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4539C9050EC27FBC00A70F4C; - remoteInfo = sample7_unittest; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; }; - 4539C94F0EC282D400A70F4C /* PBXContainerItemProxy */ = { + 40C8499B101A36DC0083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; + remoteGlobalIDString = 40C8490A101A217E0083642A; + remoteInfo = "gtest_main-static"; }; - 4539C95E0EC2833100A70F4C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4539C94D0EC282D400A70F4C; - remoteInfo = "gtest-param-test_test"; - }; - 4539C9950EC283A800A70F4C /* PBXContainerItemProxy */ = { + 40C8499D101A36E50083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; + remoteInfo = "gtest-framework"; }; - 4539C9A40EC2840700A70F4C /* PBXContainerItemProxy */ = { + 40C8499F101A36F10083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = gtest; + remoteInfo = "gtest-framework"; }; - 4539C9B00EC284C300A70F4C /* PBXContainerItemProxy */ = { + 40C849F6101A43440083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4539C9A20EC2840700A70F4C; - remoteInfo = "gtest-linked_ptr_test"; + remoteGlobalIDString = 40C8497A101A36850083642A; + remoteInfo = "gtest_unittest-static"; }; - 4539C9B20EC284C300A70F4C /* PBXContainerItemProxy */ = { + 40C849F8101A43490083642A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4539C9930EC283A800A70F4C; - remoteInfo = "gtest-port_test"; + remoteGlobalIDString = 40C84989101A36A60083642A; + remoteInfo = "sample1_unittest-static"; }; /* End PBXContainerItemProxy section */ @@ -824,208 +189,19 @@ 4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */, 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */, 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */, + 40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */, 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */, ); name = "Copy Headers Internal"; runOnlyForDeploymentPostprocessing = 0; }; - 40538A0F0ED71AF200AF209A /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 40538A180ED71B2E00AF209A /* gtest_xml_outfiles_test.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 408454300E96D39000AC66C2 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 408454350E96D3F600AC66C2 /* gtest_test_utils.py in CopyFiles */, - 4084548F0E97066B00AC66C2 /* gtest_xml_test_utils.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4084548E0E96DDBD00AC66C2 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 4084548A0E96DD8200AC66C2 /* gtest_nc_test.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A767D0ED7398700E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A76A30ED73B5500E08B81 /* gtest_break_on_failure_unittest.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A76AA0ED73BC100E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A76A20ED73B4D00E08B81 /* gtest_color_test.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A76AB0ED73BC100E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A76A10ED73B4600E08B81 /* gtest_env_var_test.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A76AC0ED73BC100E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A769E0ED73B3800E08B81 /* gtest_filter_unittest.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A76AD0ED73BC100E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A769B0ED73B2E00E08B81 /* gtest_list_tests_unittest.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A76AE0ED73BC100E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A76970ED73B2500E08B81 /* gtest_output_test.py in CopyFiles */, - 409A76980ED73B2500E08B81 /* gtest_output_test_golden_lin.txt in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A76AF0ED73BC100E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A76940ED73B0500E08B81 /* gtest_xml_output_unittest.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 409A76B00ED73BC100E08B81 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - 409A76910ED73AF200E08B81 /* gtest_uninitialized_test.py in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 222ECC990E9EB33A00BEED94 /* gtest_sole_header_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_sole_header_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 222ECCAC0E9EB47B00BEED94 /* gtest_test_part_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_test_part_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 224A129F0E9EAD8F00BD17FD /* gtest-test-part.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-test-part.cc"; sourceTree = "<group>"; }; 224A12A10E9EADA700BD17FD /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = "<group>"; }; 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "gtest-test-part.h"; sourceTree = "<group>"; }; - 22A865FC0E70A35700F7AE6E /* gtest-typed-test.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-typed-test.cc"; sourceTree = "<group>"; }; - 22A866180E70A41000F7AE6E /* sample6_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sample6_unittest.cc; sourceTree = "<group>"; }; - 3B238BF10E7FE13B00846E11 /* gtest-death-test_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-death-test_test.cc"; sourceTree = "<group>"; }; - 3B238BF20E7FE13B00846E11 /* gtest-filepath_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-filepath_test.cc"; sourceTree = "<group>"; }; - 3B238BF30E7FE13B00846E11 /* gtest-message_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-message_test.cc"; sourceTree = "<group>"; }; - 3B238BF40E7FE13B00846E11 /* gtest-options_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-options_test.cc"; sourceTree = "<group>"; }; - 3B238BF50E7FE13B00846E11 /* gtest-typed-test2_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-typed-test2_test.cc"; sourceTree = "<group>"; }; - 3B238BF60E7FE13B00846E11 /* gtest-typed-test_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-typed-test_test.cc"; sourceTree = "<group>"; }; - 3B238BF70E7FE13B00846E11 /* gtest-typed-test_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test_test.h"; sourceTree = "<group>"; }; - 3B238BF80E7FE13B00846E11 /* gtest_break_on_failure_unittest.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_break_on_failure_unittest.py; sourceTree = "<group>"; }; - 3B238BF90E7FE13B00846E11 /* gtest_break_on_failure_unittest_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_break_on_failure_unittest_.cc; sourceTree = "<group>"; }; - 3B238BFA0E7FE13B00846E11 /* gtest_color_test.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_color_test.py; sourceTree = "<group>"; }; - 3B238BFB0E7FE13B00846E11 /* gtest_color_test_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_color_test_.cc; sourceTree = "<group>"; }; - 3B238BFC0E7FE13B00846E11 /* gtest_env_var_test.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_env_var_test.py; sourceTree = "<group>"; }; - 3B238BFD0E7FE13B00846E11 /* gtest_env_var_test_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_env_var_test_.cc; sourceTree = "<group>"; }; - 3B238BFE0E7FE13B00846E11 /* gtest_environment_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_environment_test.cc; sourceTree = "<group>"; }; - 3B238BFF0E7FE13B00846E11 /* gtest_filter_unittest.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_filter_unittest.py; sourceTree = "<group>"; }; - 3B238C000E7FE13B00846E11 /* gtest_filter_unittest_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_filter_unittest_.cc; sourceTree = "<group>"; }; - 3B238C010E7FE13B00846E11 /* gtest_list_tests_unittest.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_list_tests_unittest.py; sourceTree = "<group>"; }; - 3B238C020E7FE13B00846E11 /* gtest_list_tests_unittest_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_list_tests_unittest_.cc; sourceTree = "<group>"; }; - 3B238C030E7FE13B00846E11 /* gtest_main_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main_unittest.cc; sourceTree = "<group>"; }; - 3B238C040E7FE13B00846E11 /* gtest_nc.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_nc.cc; sourceTree = "<group>"; }; - 3B238C050E7FE13B00846E11 /* gtest_nc_test.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_nc_test.py; sourceTree = "<group>"; }; - 3B238C060E7FE13B00846E11 /* gtest_no_test_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_no_test_unittest.cc; sourceTree = "<group>"; }; - 3B238C070E7FE13B00846E11 /* gtest_output_test.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_output_test.py; sourceTree = "<group>"; }; - 3B238C080E7FE13B00846E11 /* gtest_output_test_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_output_test_.cc; sourceTree = "<group>"; }; - 3B238C090E7FE13B00846E11 /* gtest_output_test_golden_lin.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = gtest_output_test_golden_lin.txt; sourceTree = "<group>"; }; - 3B238C0A0E7FE13B00846E11 /* gtest_output_test_golden_win.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = gtest_output_test_golden_win.txt; sourceTree = "<group>"; }; - 3B238C0B0E7FE13B00846E11 /* gtest_pred_impl_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_pred_impl_unittest.cc; sourceTree = "<group>"; }; - 3B238C0C0E7FE13C00846E11 /* gtest_prod_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_prod_test.cc; sourceTree = "<group>"; }; - 3B238C0D0E7FE13C00846E11 /* gtest_repeat_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_repeat_test.cc; sourceTree = "<group>"; }; - 3B238C0E0E7FE13C00846E11 /* gtest-test-part_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-test-part_test.cc"; sourceTree = "<group>"; }; - 3B238C0F0E7FE13C00846E11 /* gtest_test_utils.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_test_utils.py; sourceTree = "<group>"; }; - 3B238C100E7FE13C00846E11 /* gtest_uninitialized_test.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_uninitialized_test.py; sourceTree = "<group>"; }; - 3B238C110E7FE13C00846E11 /* gtest_uninitialized_test_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_uninitialized_test_.cc; sourceTree = "<group>"; }; 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_unittest.cc; sourceTree = "<group>"; }; - 3B238C130E7FE13C00846E11 /* gtest_xml_outfile1_test_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_xml_outfile1_test_.cc; sourceTree = "<group>"; }; - 3B238C140E7FE13C00846E11 /* gtest_xml_outfile2_test_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_xml_outfile2_test_.cc; sourceTree = "<group>"; }; - 3B238C150E7FE13C00846E11 /* gtest_xml_outfiles_test.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_xml_outfiles_test.py; sourceTree = "<group>"; }; - 3B238C160E7FE13C00846E11 /* gtest_xml_output_unittest.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_xml_output_unittest.py; sourceTree = "<group>"; }; - 3B238C170E7FE13C00846E11 /* gtest_xml_output_unittest_.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_xml_output_unittest_.cc; sourceTree = "<group>"; }; - 3B238C180E7FE13C00846E11 /* gtest_xml_test_utils.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = gtest_xml_test_utils.py; sourceTree = "<group>"; }; - 3B238C190E7FE13C00846E11 /* production.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = production.cc; sourceTree = "<group>"; }; - 3B238C1A0E7FE13C00846E11 /* production.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = production.h; sourceTree = "<group>"; }; - 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = InternalTestTarget.xcconfig; sourceTree = "<group>"; }; - 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = TestTarget.xcconfig; sourceTree = "<group>"; }; 3B87D2100E96B92E000D1852 /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = "<group>"; }; - 3B87D22F0E96C038000D1852 /* sample1_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample1_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2320E96C038000D1852 /* sample3_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample3_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2350E96C038000D1852 /* sample2_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample2_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2380E96C038000D1852 /* sample4_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample4_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D23B0E96C038000D1852 /* gtest_xml_output_unittest_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_xml_output_unittest_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D23E0E96C038000D1852 /* gtest_xml_outfile2_test_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_xml_outfile2_test_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2410E96C038000D1852 /* gtest_xml_outfile1_test_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_xml_outfile1_test_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2440E96C038000D1852 /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2470E96C038000D1852 /* gtest_uninitialized_test_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_uninitialized_test_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D24A0E96C038000D1852 /* gtest_stress_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_stress_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D24D0E96C038000D1852 /* gtest_repeat_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_repeat_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2500E96C038000D1852 /* gtest_prod_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_prod_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2530E96C038000D1852 /* gtest_pred_impl_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_pred_impl_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2560E96C038000D1852 /* gtest_output_test_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_output_test_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2590E96C038000D1852 /* gtest_no_test_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_no_test_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D25C0E96C038000D1852 /* gtest_nc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_nc; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D25F0E96C038000D1852 /* gtest_main_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_main_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2620E96C038000D1852 /* gtest_list_tests_unittest_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_list_tests_unittest_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2650E96C039000D1852 /* gtest_filter_unittest_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_filter_unittest_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2680E96C039000D1852 /* gtest_environment_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_environment_test; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D26B0E96C039000D1852 /* gtest_env_var_test_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_env_var_test_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D26E0E96C039000D1852 /* gtest_color_test_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_color_test_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2710E96C039000D1852 /* gtest_break_on_failure_unittest_ */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_break_on_failure_unittest_; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2740E96C039000D1852 /* gtest-typed-test_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-typed-test_test"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D27A0E96C039000D1852 /* gtest-options_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-options_test"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D27D0E96C039000D1852 /* gtest-message_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-message_test"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2800E96C039000D1852 /* sample5_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample5_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2830E96C039000D1852 /* sample6_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample6_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2860E96C039000D1852 /* gtest-death-test_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-death-test_test"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B87D2890E96C039000D1852 /* gtest-filepath_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-filepath_test"; sourceTree = BUILT_PRODUCTS_DIR; }; 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-type-util.h"; sourceTree = "<group>"; }; 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test.h"; sourceTree = "<group>"; }; 403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = "<group>"; }; @@ -1041,348 +217,67 @@ 404883E50E2F799B00CF7658 /* gtest-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-port.h"; sourceTree = "<group>"; }; 404883E60E2F799B00CF7658 /* gtest-string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-string.h"; sourceTree = "<group>"; }; 404883F60E2F799B00CF7658 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; }; - 404883F80E2F799B00CF7658 /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = "<group>"; }; - 404883F90E2F799B00CF7658 /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = "<group>"; }; - 404883FA0E2F799B00CF7658 /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = "<group>"; }; - 404883FB0E2F799B00CF7658 /* sample2.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample2.cc; sourceTree = "<group>"; }; - 404883FC0E2F799B00CF7658 /* sample2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample2.h; sourceTree = "<group>"; }; - 404883FD0E2F799B00CF7658 /* sample2_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample2_unittest.cc; sourceTree = "<group>"; }; - 404883FE0E2F799B00CF7658 /* sample3-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "sample3-inl.h"; sourceTree = "<group>"; }; - 404883FF0E2F799B00CF7658 /* sample3_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample3_unittest.cc; sourceTree = "<group>"; }; - 404884000E2F799B00CF7658 /* sample4.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample4.cc; sourceTree = "<group>"; }; - 404884010E2F799B00CF7658 /* sample4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample4.h; sourceTree = "<group>"; }; - 404884020E2F799B00CF7658 /* sample4_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample4_unittest.cc; sourceTree = "<group>"; }; - 404884030E2F799B00CF7658 /* sample5_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample5_unittest.cc; sourceTree = "<group>"; }; - 404884080E2F799B00CF7658 /* gtest-death-test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-death-test.cc"; sourceTree = "<group>"; }; - 404884090E2F799B00CF7658 /* gtest-filepath.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-filepath.cc"; sourceTree = "<group>"; }; - 4048840A0E2F799B00CF7658 /* gtest-internal-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-internal-inl.h"; sourceTree = "<group>"; }; - 4048840B0E2F799B00CF7658 /* gtest-port.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-port.cc"; sourceTree = "<group>"; }; - 4048840C0E2F799B00CF7658 /* gtest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest.cc; sourceTree = "<group>"; }; 4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = "<group>"; }; 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; 404884AB0E2F7CD900CF7658 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../COPYING; sourceTree = SOURCE_ROOT; }; - 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = InternalPythonTestTarget.xcconfig; sourceTree = "<group>"; }; - 40D209590E9FFBAA00191629 /* gtest_sole_header_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_sole_header_test.cc; sourceTree = "<group>"; }; - 40D2095A0E9FFBAA00191629 /* gtest_stress_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_stress_test.cc; sourceTree = "<group>"; }; + 40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = "<group>"; }; + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = "<group>"; }; + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4089A02C0FFACF7F000B29AE /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = "<group>"; }; + 4089A02D0FFACF7F000B29AE /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = "<group>"; }; + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = "<group>"; }; + 40C848FA101A209C0083642A /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C8490B101A217E0083642A /* libgtest_main.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest_main.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84987101A36850083642A /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; + 40C84997101A36A60083642A /* sample1_unittest-static */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-static"; sourceTree = BUILT_PRODUCTS_DIR; }; 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = "<group>"; }; 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = "<group>"; }; 40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = "<group>"; }; 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = "<group>"; }; 40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4539C90F0EC27FBC00A70F4C /* sample7_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample7_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 4539C91B0EC27FC000A70F4C /* sample8_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample8_unittest; sourceTree = BUILT_PRODUCTS_DIR; }; - 4539C91D0EC2800600A70F4C /* sample7_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample7_unittest.cc; sourceTree = "<group>"; }; - 4539C91F0EC2801E00A70F4C /* sample8_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample8_unittest.cc; sourceTree = "<group>"; }; - 4539C9210EC2805500A70F4C /* prime_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prime_tables.h; sourceTree = "<group>"; }; 4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = "<group>"; }; 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = "<group>"; }; 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = "<group>"; }; 4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = "<group>"; }; - 4539C9580EC282D400A70F4C /* gtest-param-test_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-param-test_test"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4539C95A0EC2830E00A70F4C /* gtest-param-test2_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-param-test2_test.cc"; sourceTree = "<group>"; }; - 4539C95B0EC2830E00A70F4C /* gtest-param-test_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-param-test_test.cc"; sourceTree = "<group>"; }; - 4539C99E0EC283A800A70F4C /* gtest-port_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-port_test"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4539C9A00EC283E400A70F4C /* gtest-port_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-port_test.cc"; sourceTree = "<group>"; }; - 4539C9AC0EC2840700A70F4C /* gtest-linked_ptr_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-linked_ptr_test"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4539C9AE0EC2843000A70F4C /* gtest-linked_ptr_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-linked_ptr_test.cc"; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 222ECC940E9EB33A00BEED94 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDD00ED5C5D2008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 222ECCA70E9EB47B00BEED94 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDCE0ED5C5D0008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 22A866070E70A39900F7AE6E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDE40ED5C5F6008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238C650E81B8B500846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDE00ED5C5F3008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238D570E82855F00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDDF0ED5C5F2008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238D680E8285DA00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDDE0ED5C5F1008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238D780E82868F00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDDD0ED5C5F1008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E130E82887E00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDCD0ED5C5D0008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E1E0E82888500846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC80ED5C5CC008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E2B0E82888800846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDCB0ED5C5CE008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E3A0E82889000846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDCA0ED5C5CD008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E450E82889500846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDDB0ED5C5EF008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E520E82889800846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC90ED5C5CC008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E5F0E82889B00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC70ED5C5CB008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E7E0E82894300846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDD90ED5C5ED008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E890E82894800846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC20ED5C5C8008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E960E82894A00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDDA0ED5C5EE008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EA30E82894D00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDCC0ED5C5CF008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EB00E82894F00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDDC0ED5C5EF008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EC70E8289C100846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDD20ED5C5D6008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238ED20E8289C300846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDD10ED5C5D3008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EDF0E8289C700846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDCF0ED5C5D1008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EEA0E8289C900846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC30ED5C5C8008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EF70E8289CE00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDE10ED5C5F3008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238F0E0E828A3800846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC50ED5C5CA008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238F190E828A3B00846E11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC40ED5C5C9008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238F260E828A3D00846E11 /* Frameworks */ = { + 40899F410FFA7184000B29AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4060FDC60ED5C5CB008BAC1E /* gtest.framework in Frameworks */, + 40C849A4101A37150083642A /* gtest.framework in Frameworks */, + 40C84916101A235B0083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 404885910E2F814C00CF7658 /* Frameworks */ = { + 4089A0110FFACEFC000B29AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4060FDE90ED5C5FB008BAC1E /* gtest.framework in Frameworks */, + 40C849A2101A37050083642A /* gtest.framework in Frameworks */, + 40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 404885B60E2F82BA00CF7658 /* Frameworks */ = { + 40C84981101A36850083642A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4060FDE80ED5C5FB008BAC1E /* gtest.framework in Frameworks */, + 40C84982101A36850083642A /* libgtest.a in Frameworks */, + 40C84983101A36850083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 404885DA0E2F832A00CF7658 /* Frameworks */ = { + 40C84991101A36A60083642A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4060FDE70ED5C5FA008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 404885E70E2F833000CF7658 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDE60ED5C5F9008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 404885F40E2F833400CF7658 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDE50ED5C5F9008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C90A0EC27FBC00A70F4C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDE30ED5C5F5008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9160EC27FC000A70F4C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDE20ED5C5F4008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9530EC282D400A70F4C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC10ED5C5C7008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9990EC283A800A70F4C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDC00ED5C5C7008BAC1E /* gtest.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9A70EC2840700A70F4C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4060FDBF0ED5C5C6008BAC1E /* gtest.framework in Frameworks */, + 40C84992101A36A60083642A /* libgtest.a in Frameworks */, + 40C84993101A36A60083642A /* libgtest_main.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1393,43 +288,12 @@ isa = PBXGroup; children = ( 4539C8FF0EC27F6400A70F4C /* gtest.framework */, - 3B87D22F0E96C038000D1852 /* sample1_unittest */, - 3B87D2350E96C038000D1852 /* sample2_unittest */, - 3B87D2320E96C038000D1852 /* sample3_unittest */, - 3B87D2380E96C038000D1852 /* sample4_unittest */, - 3B87D2800E96C039000D1852 /* sample5_unittest */, - 3B87D2830E96C039000D1852 /* sample6_unittest */, - 4539C90F0EC27FBC00A70F4C /* sample7_unittest */, - 4539C91B0EC27FC000A70F4C /* sample8_unittest */, - 3B87D2860E96C039000D1852 /* gtest-death-test_test */, - 3B87D2680E96C039000D1852 /* gtest_environment_test */, - 3B87D2890E96C039000D1852 /* gtest-filepath_test */, - 4539C9AC0EC2840700A70F4C /* gtest-linked_ptr_test */, - 3B87D25F0E96C038000D1852 /* gtest_main_unittest */, - 3B87D27D0E96C039000D1852 /* gtest-message_test */, - 3B87D2590E96C038000D1852 /* gtest_no_test_unittest */, - 3B87D27A0E96C039000D1852 /* gtest-options_test */, - 4539C9580EC282D400A70F4C /* gtest-param-test_test */, - 4539C99E0EC283A800A70F4C /* gtest-port_test */, - 3B87D2530E96C038000D1852 /* gtest_pred_impl_unittest */, - 3B87D2500E96C038000D1852 /* gtest_prod_test */, - 3B87D24D0E96C038000D1852 /* gtest_repeat_test */, - 222ECC990E9EB33A00BEED94 /* gtest_sole_header_test */, - 3B87D24A0E96C038000D1852 /* gtest_stress_test */, - 222ECCAC0E9EB47B00BEED94 /* gtest_test_part_test */, - 3B87D2740E96C039000D1852 /* gtest-typed-test_test */, - 3B87D2440E96C038000D1852 /* gtest_unittest */, - 3B87D2710E96C039000D1852 /* gtest_break_on_failure_unittest_ */, - 3B87D26E0E96C039000D1852 /* gtest_color_test_ */, - 3B87D26B0E96C039000D1852 /* gtest_env_var_test_ */, - 3B87D2650E96C039000D1852 /* gtest_filter_unittest_ */, - 3B87D2620E96C038000D1852 /* gtest_list_tests_unittest_ */, - 3B87D2560E96C038000D1852 /* gtest_output_test_ */, - 3B87D2410E96C038000D1852 /* gtest_xml_outfile1_test_ */, - 3B87D23E0E96C038000D1852 /* gtest_xml_outfile2_test_ */, - 3B87D23B0E96C038000D1852 /* gtest_xml_output_unittest_ */, - 3B87D2470E96C038000D1852 /* gtest_uninitialized_test_ */, - 3B87D25C0E96C038000D1852 /* gtest_nc */, + 40C848FA101A209C0083642A /* libgtest.a */, + 40C8490B101A217E0083642A /* libgtest_main.a */, + 40899F430FFA7184000B29AE /* gtest_unittest-framework */, + 40C84987101A36850083642A /* gtest_unittest */, + 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84997101A36A60083642A /* sample1_unittest-static */, ); name = Products; sourceTree = "<group>"; @@ -1454,7 +318,7 @@ 404884AB0E2F7CD900CF7658 /* COPYING */, 404883F60E2F799B00CF7658 /* README */, 404883D90E2F799B00CF7658 /* include */, - 404883F70E2F799B00CF7658 /* samples */, + 4089A02F0FFACF84000B29AE /* samples */, 404884070E2F799B00CF7658 /* src */, 3B238BF00E7FE13B00846E11 /* test */, ); @@ -1464,54 +328,7 @@ 3B238BF00E7FE13B00846E11 /* test */ = { isa = PBXGroup; children = ( - 3B238BF10E7FE13B00846E11 /* gtest-death-test_test.cc */, - 3B238BF20E7FE13B00846E11 /* gtest-filepath_test.cc */, - 4539C9AE0EC2843000A70F4C /* gtest-linked_ptr_test.cc */, - 3B238BF30E7FE13B00846E11 /* gtest-message_test.cc */, - 3B238BF40E7FE13B00846E11 /* gtest-options_test.cc */, - 4539C95A0EC2830E00A70F4C /* gtest-param-test2_test.cc */, - 4539C95B0EC2830E00A70F4C /* gtest-param-test_test.cc */, - 4539C9A00EC283E400A70F4C /* gtest-port_test.cc */, - 3B238BF50E7FE13B00846E11 /* gtest-typed-test2_test.cc */, - 3B238BF60E7FE13B00846E11 /* gtest-typed-test_test.cc */, - 3B238BF70E7FE13B00846E11 /* gtest-typed-test_test.h */, - 3B238BF80E7FE13B00846E11 /* gtest_break_on_failure_unittest.py */, - 3B238BF90E7FE13B00846E11 /* gtest_break_on_failure_unittest_.cc */, - 3B238BFA0E7FE13B00846E11 /* gtest_color_test.py */, - 3B238BFB0E7FE13B00846E11 /* gtest_color_test_.cc */, - 3B238BFC0E7FE13B00846E11 /* gtest_env_var_test.py */, - 3B238BFD0E7FE13B00846E11 /* gtest_env_var_test_.cc */, - 3B238BFE0E7FE13B00846E11 /* gtest_environment_test.cc */, - 3B238BFF0E7FE13B00846E11 /* gtest_filter_unittest.py */, - 3B238C000E7FE13B00846E11 /* gtest_filter_unittest_.cc */, - 3B238C010E7FE13B00846E11 /* gtest_list_tests_unittest.py */, - 3B238C020E7FE13B00846E11 /* gtest_list_tests_unittest_.cc */, - 3B238C030E7FE13B00846E11 /* gtest_main_unittest.cc */, - 3B238C040E7FE13B00846E11 /* gtest_nc.cc */, - 3B238C050E7FE13B00846E11 /* gtest_nc_test.py */, - 3B238C060E7FE13B00846E11 /* gtest_no_test_unittest.cc */, - 3B238C070E7FE13B00846E11 /* gtest_output_test.py */, - 3B238C080E7FE13B00846E11 /* gtest_output_test_.cc */, - 3B238C090E7FE13B00846E11 /* gtest_output_test_golden_lin.txt */, - 3B238C0A0E7FE13B00846E11 /* gtest_output_test_golden_win.txt */, - 3B238C0B0E7FE13B00846E11 /* gtest_pred_impl_unittest.cc */, - 3B238C0C0E7FE13C00846E11 /* gtest_prod_test.cc */, - 3B238C0D0E7FE13C00846E11 /* gtest_repeat_test.cc */, - 40D209590E9FFBAA00191629 /* gtest_sole_header_test.cc */, - 40D2095A0E9FFBAA00191629 /* gtest_stress_test.cc */, - 3B238C0E0E7FE13C00846E11 /* gtest-test-part_test.cc */, - 3B238C0F0E7FE13C00846E11 /* gtest_test_utils.py */, - 3B238C100E7FE13C00846E11 /* gtest_uninitialized_test.py */, - 3B238C110E7FE13C00846E11 /* gtest_uninitialized_test_.cc */, 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */, - 3B238C130E7FE13C00846E11 /* gtest_xml_outfile1_test_.cc */, - 3B238C140E7FE13C00846E11 /* gtest_xml_outfile2_test_.cc */, - 3B238C150E7FE13C00846E11 /* gtest_xml_outfiles_test.py */, - 3B238C160E7FE13C00846E11 /* gtest_xml_output_unittest.py */, - 3B238C170E7FE13C00846E11 /* gtest_xml_output_unittest_.cc */, - 3B238C180E7FE13C00846E11 /* gtest_xml_test_utils.py */, - 3B238C190E7FE13C00846E11 /* production.cc */, - 3B238C1A0E7FE13C00846E11 /* production.h */, ); name = test; path = ../test; @@ -1563,62 +380,41 @@ 4539C9370EC280E200A70F4C /* gtest-param-util.h */, 404883E50E2F799B00CF7658 /* gtest-port.h */, 404883E60E2F799B00CF7658 /* gtest-string.h */, + 40899F4D0FFA7271000B29AE /* gtest-tuple.h */, 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */, ); path = internal; sourceTree = "<group>"; }; - 404883F70E2F799B00CF7658 /* samples */ = { - isa = PBXGroup; - children = ( - 4539C9210EC2805500A70F4C /* prime_tables.h */, - 404883F80E2F799B00CF7658 /* sample1.cc */, - 404883F90E2F799B00CF7658 /* sample1.h */, - 404883FA0E2F799B00CF7658 /* sample1_unittest.cc */, - 404883FB0E2F799B00CF7658 /* sample2.cc */, - 404883FC0E2F799B00CF7658 /* sample2.h */, - 404883FD0E2F799B00CF7658 /* sample2_unittest.cc */, - 404883FE0E2F799B00CF7658 /* sample3-inl.h */, - 404883FF0E2F799B00CF7658 /* sample3_unittest.cc */, - 404884000E2F799B00CF7658 /* sample4.cc */, - 404884010E2F799B00CF7658 /* sample4.h */, - 404884020E2F799B00CF7658 /* sample4_unittest.cc */, - 404884030E2F799B00CF7658 /* sample5_unittest.cc */, - 22A866180E70A41000F7AE6E /* sample6_unittest.cc */, - 4539C91F0EC2801E00A70F4C /* sample8_unittest.cc */, - 4539C91D0EC2800600A70F4C /* sample7_unittest.cc */, - ); - name = samples; - path = ../samples; - sourceTree = SOURCE_ROOT; - }; 404884070E2F799B00CF7658 /* src */ = { isa = PBXGroup; children = ( 224A12A10E9EADA700BD17FD /* gtest-all.cc */, - 224A129F0E9EAD8F00BD17FD /* gtest-test-part.cc */, - 404884080E2F799B00CF7658 /* gtest-death-test.cc */, - 404884090E2F799B00CF7658 /* gtest-filepath.cc */, - 4048840A0E2F799B00CF7658 /* gtest-internal-inl.h */, - 4048840B0E2F799B00CF7658 /* gtest-port.cc */, - 4048840C0E2F799B00CF7658 /* gtest.cc */, 4048840D0E2F799B00CF7658 /* gtest_main.cc */, - 22A865FC0E70A35700F7AE6E /* gtest-typed-test.cc */, ); name = src; path = ../src; sourceTree = SOURCE_ROOT; }; + 4089A02F0FFACF84000B29AE /* samples */ = { + isa = PBXGroup; + children = ( + 4089A02C0FFACF7F000B29AE /* sample1.cc */, + 4089A02D0FFACF7F000B29AE /* sample1.h */, + 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */, + ); + name = samples; + path = ../samples; + sourceTree = SOURCE_ROOT; + }; 40D4CDF00E30E07400294801 /* Config */ = { isa = PBXGroup; children = ( 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */, 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */, 40D4CDF30E30E07400294801 /* General.xcconfig */, - 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */, - 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */, 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */, - 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */, + 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */, ); path = Config; sourceTree = "<group>"; @@ -1653,668 +449,123 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 222ECC8F0E9EB33A00BEED94 /* gtest_sole_header_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 222ECC960E9EB33A00BEED94 /* Build configuration list for PBXNativeTarget "gtest_sole_header_test" */; - buildPhases = ( - 222ECC920E9EB33A00BEED94 /* Sources */, - 222ECC940E9EB33A00BEED94 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 222ECC900E9EB33A00BEED94 /* PBXTargetDependency */, - ); - name = gtest_sole_header_test; - productName = TypedTest2; - productReference = 222ECC990E9EB33A00BEED94 /* gtest_sole_header_test */; - productType = "com.apple.product-type.tool"; - }; - 222ECCA20E9EB47B00BEED94 /* gtest_test_part_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 222ECCA90E9EB47B00BEED94 /* Build configuration list for PBXNativeTarget "gtest_test_part_test" */; - buildPhases = ( - 222ECCA50E9EB47B00BEED94 /* Sources */, - 222ECCA70E9EB47B00BEED94 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 222ECCA30E9EB47B00BEED94 /* PBXTargetDependency */, - ); - name = gtest_test_part_test; - productName = TypedTest2; - productReference = 222ECCAC0E9EB47B00BEED94 /* gtest_test_part_test */; - productType = "com.apple.product-type.tool"; - }; - 22A866010E70A39900F7AE6E /* sample6_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 22A866090E70A39900F7AE6E /* Build configuration list for PBXNativeTarget "sample6_unittest" */; - buildPhases = ( - 22A866040E70A39900F7AE6E /* Sources */, - 22A866070E70A39900F7AE6E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 22A866020E70A39900F7AE6E /* PBXTargetDependency */, - ); - name = sample6_unittest; - productName = sample6; - productReference = 3B87D2830E96C039000D1852 /* sample6_unittest */; - productType = "com.apple.product-type.tool"; - }; - 3B238C660E81B8B500846E11 /* gtest-death-test_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238CD20E81B94000846E11 /* Build configuration list for PBXNativeTarget "gtest-death-test_test" */; - buildPhases = ( - 3B238C640E81B8B500846E11 /* Sources */, - 3B238C650E81B8B500846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238C990E81B92000846E11 /* PBXTargetDependency */, - ); - name = "gtest-death-test_test"; - productName = Test; - productReference = 3B87D2860E96C039000D1852 /* gtest-death-test_test */; - productType = "com.apple.product-type.tool"; - }; - 3B238D520E82855F00846E11 /* gtest-filepath_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238D590E82855F00846E11 /* Build configuration list for PBXNativeTarget "gtest-filepath_test" */; - buildPhases = ( - 3B238D550E82855F00846E11 /* Sources */, - 3B238D570E82855F00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238D530E82855F00846E11 /* PBXTargetDependency */, - ); - name = "gtest-filepath_test"; - productName = Test; - productReference = 3B87D2890E96C039000D1852 /* gtest-filepath_test */; - productType = "com.apple.product-type.tool"; - }; - 3B238D690E8285DA00846E11 /* gtest-message_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238D6F0E82862800846E11 /* Build configuration list for PBXNativeTarget "gtest-message_test" */; - buildPhases = ( - 3B238D670E8285DA00846E11 /* Sources */, - 3B238D680E8285DA00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238D710E82862D00846E11 /* PBXTargetDependency */, - ); - name = "gtest-message_test"; - productName = MessageTest; - productReference = 3B87D27D0E96C039000D1852 /* gtest-message_test */; - productType = "com.apple.product-type.tool"; - }; - 3B238D790E82868F00846E11 /* gtest-options_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238D9D0E8286ED00846E11 /* Build configuration list for PBXNativeTarget "gtest-options_test" */; - buildPhases = ( - 3B238D770E82868F00846E11 /* Sources */, - 3B238D780E82868F00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238D7F0E82869400846E11 /* PBXTargetDependency */, - ); - name = "gtest-options_test"; - productName = OptionsTest; - productReference = 3B87D27A0E96C039000D1852 /* gtest-options_test */; - productType = "com.apple.product-type.tool"; - }; - 3B238E0F0E82887E00846E11 /* gtest-typed-test_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E150E82887E00846E11 /* Build configuration list for PBXNativeTarget "gtest-typed-test_test" */; - buildPhases = ( - 3B238E120E82887E00846E11 /* Sources */, - 3B238E130E82887E00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238E100E82887E00846E11 /* PBXTargetDependency */, - ); - name = "gtest-typed-test_test"; - productName = TypedTest2; - productReference = 3B87D2740E96C039000D1852 /* gtest-typed-test_test */; - productType = "com.apple.product-type.tool"; - }; - 3B238E1A0E82888500846E11 /* gtest_break_on_failure_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E200E82888500846E11 /* Build configuration list for PBXNativeTarget "gtest_break_on_failure_unittest" */; - buildPhases = ( - 3B238E1D0E82888500846E11 /* Sources */, - 3B238E1E0E82888500846E11 /* Frameworks */, - 409A767D0ED7398700E08B81 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - 409A76540ED7393100E08B81 /* PBXTargetDependency */, - 3B238E1B0E82888500846E11 /* PBXTargetDependency */, - ); - name = gtest_break_on_failure_unittest; - productName = TypedTest2; - productReference = 3B87D2710E96C039000D1852 /* gtest_break_on_failure_unittest_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238E270E82888800846E11 /* gtest_color_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E2D0E82888800846E11 /* Build configuration list for PBXNativeTarget "gtest_color_test" */; - buildPhases = ( - 3B238E2A0E82888800846E11 /* Sources */, - 3B238E2B0E82888800846E11 /* Frameworks */, - 409A76AA0ED73BC100E08B81 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - 409A76580ED7393800E08B81 /* PBXTargetDependency */, - 3B238E280E82888800846E11 /* PBXTargetDependency */, - ); - name = gtest_color_test; - productName = TypedTest2; - productReference = 3B87D26E0E96C039000D1852 /* gtest_color_test_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238E360E82889000846E11 /* gtest_env_var_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E3C0E82889000846E11 /* Build configuration list for PBXNativeTarget "gtest_env_var_test" */; - buildPhases = ( - 3B238E390E82889000846E11 /* Sources */, - 3B238E3A0E82889000846E11 /* Frameworks */, - 409A76AB0ED73BC100E08B81 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - 409A765C0ED7393D00E08B81 /* PBXTargetDependency */, - 3B238E370E82889000846E11 /* PBXTargetDependency */, - ); - name = gtest_env_var_test; - productName = TypedTest2; - productReference = 3B87D26B0E96C039000D1852 /* gtest_env_var_test_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238E410E82889500846E11 /* gtest_environment_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E470E82889500846E11 /* Build configuration list for PBXNativeTarget "gtest_environment_test" */; - buildPhases = ( - 3B238E440E82889500846E11 /* Sources */, - 3B238E450E82889500846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238E420E82889500846E11 /* PBXTargetDependency */, - ); - name = gtest_environment_test; - productName = TypedTest2; - productReference = 3B87D2680E96C039000D1852 /* gtest_environment_test */; - productType = "com.apple.product-type.tool"; - }; - 3B238E4E0E82889800846E11 /* gtest_filter_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E540E82889800846E11 /* Build configuration list for PBXNativeTarget "gtest_filter_unittest" */; - buildPhases = ( - 3B238E510E82889800846E11 /* Sources */, - 3B238E520E82889800846E11 /* Frameworks */, - 409A76AC0ED73BC100E08B81 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - 3B238E4F0E82889800846E11 /* PBXTargetDependency */, - ); - name = gtest_filter_unittest; - productName = TypedTest2; - productReference = 3B87D2650E96C039000D1852 /* gtest_filter_unittest_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238E5B0E82889B00846E11 /* gtest_list_tests_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E610E82889B00846E11 /* Build configuration list for PBXNativeTarget "gtest_list_tests_unittest" */; - buildPhases = ( - 3B238E5E0E82889B00846E11 /* Sources */, - 3B238E5F0E82889B00846E11 /* Frameworks */, - 409A76AD0ED73BC100E08B81 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - 409A76600ED7394200E08B81 /* PBXTargetDependency */, - 3B238E5C0E82889B00846E11 /* PBXTargetDependency */, - ); - name = gtest_list_tests_unittest; - productName = TypedTest2; - productReference = 3B87D2620E96C038000D1852 /* gtest_list_tests_unittest_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238E7A0E82894300846E11 /* gtest_main_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E800E82894300846E11 /* Build configuration list for PBXNativeTarget "gtest_main_unittest" */; - buildPhases = ( - 3B238E7D0E82894300846E11 /* Sources */, - 3B238E7E0E82894300846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238E7B0E82894300846E11 /* PBXTargetDependency */, - ); - name = gtest_main_unittest; - productName = TypedTest2; - productReference = 3B87D25F0E96C038000D1852 /* gtest_main_unittest */; - productType = "com.apple.product-type.tool"; - }; - 3B238E850E82894800846E11 /* gtest_nc */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E8B0E82894800846E11 /* Build configuration list for PBXNativeTarget "gtest_nc" */; - buildPhases = ( - 3B238E880E82894800846E11 /* Sources */, - 3B238E890E82894800846E11 /* Frameworks */, - 4084548E0E96DDBD00AC66C2 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - 4084546D0E96D70C00AC66C2 /* PBXTargetDependency */, - 3B238E860E82894800846E11 /* PBXTargetDependency */, - ); - name = gtest_nc; - productName = TypedTest2; - productReference = 3B87D25C0E96C038000D1852 /* gtest_nc */; - productType = "com.apple.product-type.tool"; - }; - 3B238E920E82894A00846E11 /* gtest_no_test_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238E980E82894A00846E11 /* Build configuration list for PBXNativeTarget "gtest_no_test_unittest" */; - buildPhases = ( - 3B238E950E82894A00846E11 /* Sources */, - 3B238E960E82894A00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238E930E82894A00846E11 /* PBXTargetDependency */, - ); - name = gtest_no_test_unittest; - productName = TypedTest2; - productReference = 3B87D2590E96C038000D1852 /* gtest_no_test_unittest */; - productType = "com.apple.product-type.tool"; - }; - 3B238E9F0E82894D00846E11 /* gtest_output_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238EA50E82894D00846E11 /* Build configuration list for PBXNativeTarget "gtest_output_test" */; - buildPhases = ( - 3B238EA20E82894D00846E11 /* Sources */, - 3B238EA30E82894D00846E11 /* Frameworks */, - 409A76AE0ED73BC100E08B81 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - 409A76640ED7394500E08B81 /* PBXTargetDependency */, - 3B238EA00E82894D00846E11 /* PBXTargetDependency */, - ); - name = gtest_output_test; - productName = TypedTest2; - productReference = 3B87D2560E96C038000D1852 /* gtest_output_test_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238EAC0E82894F00846E11 /* gtest_pred_impl_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238EB20E82894F00846E11 /* Build configuration list for PBXNativeTarget "gtest_pred_impl_unittest" */; - buildPhases = ( - 3B238EAF0E82894F00846E11 /* Sources */, - 3B238EB00E82894F00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238EAD0E82894F00846E11 /* PBXTargetDependency */, - ); - name = gtest_pred_impl_unittest; - productName = TypedTest2; - productReference = 3B87D2530E96C038000D1852 /* gtest_pred_impl_unittest */; - productType = "com.apple.product-type.tool"; - }; - 3B238EC30E8289C100846E11 /* gtest_prod_test */ = { + 40899F420FFA7184000B29AE /* gtest_unittest-framework */ = { isa = PBXNativeTarget; - buildConfigurationList = 3B238EC90E8289C100846E11 /* Build configuration list for PBXNativeTarget "gtest_prod_test" */; + buildConfigurationList = 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */; buildPhases = ( - 3B238EC60E8289C100846E11 /* Sources */, - 3B238EC70E8289C100846E11 /* Frameworks */, + 40899F400FFA7184000B29AE /* Sources */, + 40899F410FFA7184000B29AE /* Frameworks */, ); buildRules = ( ); dependencies = ( - 3B238EC40E8289C100846E11 /* PBXTargetDependency */, + 40C849A0101A36F10083642A /* PBXTargetDependency */, ); - name = gtest_prod_test; - productName = TypedTest2; - productReference = 3B87D2500E96C038000D1852 /* gtest_prod_test */; + name = "gtest_unittest-framework"; + productName = gtest_unittest; + productReference = 40899F430FFA7184000B29AE /* gtest_unittest-framework */; productType = "com.apple.product-type.tool"; }; - 3B238ECE0E8289C300846E11 /* gtest_repeat_test */ = { + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */ = { isa = PBXNativeTarget; - buildConfigurationList = 3B238ED40E8289C300846E11 /* Build configuration list for PBXNativeTarget "gtest_repeat_test" */; + buildConfigurationList = 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */; buildPhases = ( - 3B238ED10E8289C300846E11 /* Sources */, - 3B238ED20E8289C300846E11 /* Frameworks */, + 4089A0100FFACEFC000B29AE /* Sources */, + 4089A0110FFACEFC000B29AE /* Frameworks */, ); buildRules = ( ); dependencies = ( - 3B238ECF0E8289C300846E11 /* PBXTargetDependency */, + 40C8499E101A36E50083642A /* PBXTargetDependency */, ); - name = gtest_repeat_test; - productName = TypedTest2; - productReference = 3B87D24D0E96C038000D1852 /* gtest_repeat_test */; + name = "sample1_unittest-framework"; + productName = sample1_unittest; + productReference = 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */; productType = "com.apple.product-type.tool"; }; - 3B238EDB0E8289C700846E11 /* gtest_stress_test */ = { + 40C848F9101A209C0083642A /* gtest-static */ = { isa = PBXNativeTarget; - buildConfigurationList = 3B238EE10E8289C700846E11 /* Build configuration list for PBXNativeTarget "gtest_stress_test" */; + buildConfigurationList = 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */; buildPhases = ( - 3B238EDE0E8289C700846E11 /* Sources */, - 3B238EDF0E8289C700846E11 /* Frameworks */, + 40C848F7101A209C0083642A /* Sources */, ); buildRules = ( ); dependencies = ( - 3B238EDC0E8289C700846E11 /* PBXTargetDependency */, ); - name = gtest_stress_test; - productName = TypedTest2; - productReference = 3B87D24A0E96C038000D1852 /* gtest_stress_test */; - productType = "com.apple.product-type.tool"; + name = "gtest-static"; + productName = "gtest-static"; + productReference = 40C848FA101A209C0083642A /* libgtest.a */; + productType = "com.apple.product-type.library.static"; }; - 3B238EE60E8289C900846E11 /* gtest_uninitialized_test */ = { + 40C8490A101A217E0083642A /* gtest_main-static */ = { isa = PBXNativeTarget; - buildConfigurationList = 3B238EEC0E8289C900846E11 /* Build configuration list for PBXNativeTarget "gtest_uninitialized_test" */; + buildConfigurationList = 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */; buildPhases = ( - 3B238EE90E8289C900846E11 /* Sources */, - 3B238EEA0E8289C900846E11 /* Frameworks */, - 409A76B00ED73BC100E08B81 /* CopyFiles */, + 40C84908101A217E0083642A /* Sources */, ); buildRules = ( ); dependencies = ( - 409A76740ED7395400E08B81 /* PBXTargetDependency */, - 3B238EE70E8289C900846E11 /* PBXTargetDependency */, - ); - name = gtest_uninitialized_test; - productName = TypedTest2; - productReference = 3B87D2470E96C038000D1852 /* gtest_uninitialized_test_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238EF30E8289CE00846E11 /* gtest_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238EF90E8289CE00846E11 /* Build configuration list for PBXNativeTarget "gtest_unittest" */; - buildPhases = ( - 3B238EF60E8289CE00846E11 /* Sources */, - 3B238EF70E8289CE00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238EF40E8289CE00846E11 /* PBXTargetDependency */, - ); - name = gtest_unittest; - productName = TypedTest2; - productReference = 3B87D2440E96C038000D1852 /* gtest_unittest */; - productType = "com.apple.product-type.tool"; - }; - 3B238F0A0E828A3800846E11 /* gtest_xml_outfile1_test_ */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238F100E828A3800846E11 /* Build configuration list for PBXNativeTarget "gtest_xml_outfile1_test_" */; - buildPhases = ( - 3B238F0D0E828A3800846E11 /* Sources */, - 3B238F0E0E828A3800846E11 /* Frameworks */, ); - buildRules = ( - ); - dependencies = ( - 3B238F0B0E828A3800846E11 /* PBXTargetDependency */, - ); - name = gtest_xml_outfile1_test_; - productName = TypedTest2; - productReference = 3B87D2410E96C038000D1852 /* gtest_xml_outfile1_test_ */; - productType = "com.apple.product-type.tool"; - }; - 3B238F150E828A3B00846E11 /* gtest_xml_outfile2_test_ */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3B238F1B0E828A3B00846E11 /* Build configuration list for PBXNativeTarget "gtest_xml_outfile2_test_" */; - buildPhases = ( - 3B238F180E828A3B00846E11 /* Sources */, - 3B238F190E828A3B00846E11 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 3B238F160E828A3B00846E11 /* PBXTargetDependency */, - ); - name = gtest_xml_outfile2_test_; - productName = TypedTest2; - productReference = 3B87D23E0E96C038000D1852 /* gtest_xml_outfile2_test_ */; - productType = "com.apple.product-type.tool"; + name = "gtest_main-static"; + productName = "gtest_main-static"; + productReference = 40C8490B101A217E0083642A /* libgtest_main.a */; + productType = "com.apple.product-type.library.static"; }; - 3B238F220E828A3D00846E11 /* gtest_xml_output_unittest */ = { + 40C8497A101A36850083642A /* gtest_unittest-static */ = { isa = PBXNativeTarget; - buildConfigurationList = 3B238F280E828A3D00846E11 /* Build configuration list for PBXNativeTarget "gtest_xml_output_unittest" */; + buildConfigurationList = 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */; buildPhases = ( - 3B238F250E828A3D00846E11 /* Sources */, - 3B238F260E828A3D00846E11 /* Frameworks */, - 409A76AF0ED73BC100E08B81 /* CopyFiles */, + 40C8497F101A36850083642A /* Sources */, + 40C84981101A36850083642A /* Frameworks */, ); buildRules = ( ); dependencies = ( - 409A76700ED7395000E08B81 /* PBXTargetDependency */, - 3B238F230E828A3D00846E11 /* PBXTargetDependency */, + 40C8497B101A36850083642A /* PBXTargetDependency */, + 40C8497D101A36850083642A /* PBXTargetDependency */, ); - name = gtest_xml_output_unittest; - productName = TypedTest2; - productReference = 3B87D23B0E96C038000D1852 /* gtest_xml_output_unittest_ */; + name = "gtest_unittest-static"; + productName = gtest_unittest; + productReference = 40C84987101A36850083642A /* gtest_unittest */; productType = "com.apple.product-type.tool"; }; - 404885920E2F814C00CF7658 /* sample1_unittest */ = { + 40C84989101A36A60083642A /* sample1_unittest-static */ = { isa = PBXNativeTarget; - buildConfigurationList = 4048859E0E2F818900CF7658 /* Build configuration list for PBXNativeTarget "sample1_unittest" */; + buildConfigurationList = 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */; buildPhases = ( - 404885900E2F814C00CF7658 /* Sources */, - 404885910E2F814C00CF7658 /* Frameworks */, + 40C8498E101A36A60083642A /* Sources */, + 40C84991101A36A60083642A /* Frameworks */, ); buildRules = ( ); dependencies = ( - 404885A80E2F824900CF7658 /* PBXTargetDependency */, + 40C8498A101A36A60083642A /* PBXTargetDependency */, + 40C8498C101A36A60083642A /* PBXTargetDependency */, ); - name = sample1_unittest; - productName = sample1; - productReference = 3B87D22F0E96C038000D1852 /* sample1_unittest */; + name = "sample1_unittest-static"; + productName = sample1_unittest; + productReference = 40C84997101A36A60083642A /* sample1_unittest-static */; productType = "com.apple.product-type.tool"; }; - 404885B00E2F82BA00CF7658 /* sample2_unittest */ = { + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */ = { isa = PBXNativeTarget; - buildConfigurationList = 404885B80E2F82BA00CF7658 /* Build configuration list for PBXNativeTarget "sample2_unittest" */; - buildPhases = ( - 404885B30E2F82BA00CF7658 /* Sources */, - 404885B60E2F82BA00CF7658 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 404885B10E2F82BA00CF7658 /* PBXTargetDependency */, - ); - name = sample2_unittest; - productName = sample2; - productReference = 3B87D2350E96C038000D1852 /* sample2_unittest */; - productType = "com.apple.product-type.tool"; - }; - 404885D40E2F832A00CF7658 /* sample3_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 404885DC0E2F832A00CF7658 /* Build configuration list for PBXNativeTarget "sample3_unittest" */; - buildPhases = ( - 404885D70E2F832A00CF7658 /* Sources */, - 404885DA0E2F832A00CF7658 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 404885D50E2F832A00CF7658 /* PBXTargetDependency */, - ); - name = sample3_unittest; - productName = sample3; - productReference = 3B87D2320E96C038000D1852 /* sample3_unittest */; - productType = "com.apple.product-type.tool"; - }; - 404885E10E2F833000CF7658 /* sample4_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 404885E90E2F833000CF7658 /* Build configuration list for PBXNativeTarget "sample4_unittest" */; - buildPhases = ( - 404885E40E2F833000CF7658 /* Sources */, - 404885E70E2F833000CF7658 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 404885E20E2F833000CF7658 /* PBXTargetDependency */, - ); - name = sample4_unittest; - productName = sample4; - productReference = 3B87D2380E96C038000D1852 /* sample4_unittest */; - productType = "com.apple.product-type.tool"; - }; - 404885EE0E2F833400CF7658 /* sample5_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 404885F60E2F833400CF7658 /* Build configuration list for PBXNativeTarget "sample5_unittest" */; - buildPhases = ( - 404885F10E2F833400CF7658 /* Sources */, - 404885F40E2F833400CF7658 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 404885EF0E2F833400CF7658 /* PBXTargetDependency */, - ); - name = sample5_unittest; - productName = sample5; - productReference = 3B87D2800E96C039000D1852 /* sample5_unittest */; - productType = "com.apple.product-type.tool"; - }; - 4539C9050EC27FBC00A70F4C /* sample7_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4539C90C0EC27FBC00A70F4C /* Build configuration list for PBXNativeTarget "sample7_unittest" */; - buildPhases = ( - 4539C9080EC27FBC00A70F4C /* Sources */, - 4539C90A0EC27FBC00A70F4C /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 4539C9060EC27FBC00A70F4C /* PBXTargetDependency */, - ); - name = sample7_unittest; - productName = sample6; - productReference = 4539C90F0EC27FBC00A70F4C /* sample7_unittest */; - productType = "com.apple.product-type.tool"; - }; - 4539C9110EC27FC000A70F4C /* sample8_unittest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4539C9180EC27FC000A70F4C /* Build configuration list for PBXNativeTarget "sample8_unittest" */; - buildPhases = ( - 4539C9140EC27FC000A70F4C /* Sources */, - 4539C9160EC27FC000A70F4C /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 4539C9120EC27FC000A70F4C /* PBXTargetDependency */, - ); - name = sample8_unittest; - productName = sample6; - productReference = 4539C91B0EC27FC000A70F4C /* sample8_unittest */; - productType = "com.apple.product-type.tool"; - }; - 4539C94D0EC282D400A70F4C /* gtest-param-test_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4539C9550EC282D400A70F4C /* Build configuration list for PBXNativeTarget "gtest-param-test_test" */; - buildPhases = ( - 4539C9500EC282D400A70F4C /* Sources */, - 4539C9530EC282D400A70F4C /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 4539C94E0EC282D400A70F4C /* PBXTargetDependency */, - ); - name = "gtest-param-test_test"; - productName = TypedTest2; - productReference = 4539C9580EC282D400A70F4C /* gtest-param-test_test */; - productType = "com.apple.product-type.tool"; - }; - 4539C9930EC283A800A70F4C /* gtest-port_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4539C99B0EC283A800A70F4C /* Build configuration list for PBXNativeTarget "gtest-port_test" */; - buildPhases = ( - 4539C9960EC283A800A70F4C /* Sources */, - 4539C9990EC283A800A70F4C /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 4539C9940EC283A800A70F4C /* PBXTargetDependency */, - ); - name = "gtest-port_test"; - productName = TypedTest2; - productReference = 4539C99E0EC283A800A70F4C /* gtest-port_test */; - productType = "com.apple.product-type.tool"; - }; - 4539C9A20EC2840700A70F4C /* gtest-linked_ptr_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4539C9A90EC2840700A70F4C /* Build configuration list for PBXNativeTarget "gtest-linked_ptr_test" */; - buildPhases = ( - 4539C9A50EC2840700A70F4C /* Sources */, - 4539C9A70EC2840700A70F4C /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 4539C9A30EC2840700A70F4C /* PBXTargetDependency */, - ); - name = "gtest-linked_ptr_test"; - productName = TypedTest2; - productReference = 4539C9AC0EC2840700A70F4C /* gtest-linked_ptr_test */; - productType = "com.apple.product-type.tool"; - }; - 8D07F2BC0486CC7A007CD1D0 /* gtest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest" */; + buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */; buildPhases = ( 8D07F2C10486CC7A007CD1D0 /* Sources */, 8D07F2BD0486CC7A007CD1D0 /* Headers */, 404884A50E2F7C0400CF7658 /* Copy Headers Internal */, 8D07F2BF0486CC7A007CD1D0 /* Resources */, - 8D07F2C50486CC7A007CD1D0 /* Rez */, ); buildRules = ( ); dependencies = ( 40C44AE60E379922008FCC51 /* PBXTargetDependency */, + 408BEC101046CFE900DEF522 /* PBXTargetDependency */, + 40C8499C101A36DC0083642A /* PBXTargetDependency */, ); - name = gtest; + name = "gtest-framework"; productInstallPath = "$(HOME)/Library/Frameworks"; productName = gtest; productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; @@ -2340,48 +591,15 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 8D07F2BC0486CC7A007CD1D0 /* gtest */, + 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */, + 40C848F9101A209C0083642A /* gtest-static */, + 40C8490A101A217E0083642A /* gtest_main-static */, + 40899F420FFA7184000B29AE /* gtest_unittest-framework */, + 40C8497A101A36850083642A /* gtest_unittest-static */, + 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */, + 40C84989101A36A60083642A /* sample1_unittest-static */, 3B238F5F0E828B5400846E11 /* Check */, - 404885920E2F814C00CF7658 /* sample1_unittest */, - 404885B00E2F82BA00CF7658 /* sample2_unittest */, - 404885D40E2F832A00CF7658 /* sample3_unittest */, - 404885E10E2F833000CF7658 /* sample4_unittest */, - 404885EE0E2F833400CF7658 /* sample5_unittest */, - 22A866010E70A39900F7AE6E /* sample6_unittest */, - 4539C9050EC27FBC00A70F4C /* sample7_unittest */, - 4539C9110EC27FC000A70F4C /* sample8_unittest */, - 3B238C660E81B8B500846E11 /* gtest-death-test_test */, - 3B238E410E82889500846E11 /* gtest_environment_test */, - 3B238D520E82855F00846E11 /* gtest-filepath_test */, - 4539C9A20EC2840700A70F4C /* gtest-linked_ptr_test */, - 3B238E7A0E82894300846E11 /* gtest_main_unittest */, - 3B238D690E8285DA00846E11 /* gtest-message_test */, - 3B238E920E82894A00846E11 /* gtest_no_test_unittest */, - 3B238D790E82868F00846E11 /* gtest-options_test */, - 4539C94D0EC282D400A70F4C /* gtest-param-test_test */, - 4539C9930EC283A800A70F4C /* gtest-port_test */, - 3B238EAC0E82894F00846E11 /* gtest_pred_impl_unittest */, - 3B238EC30E8289C100846E11 /* gtest_prod_test */, - 3B238ECE0E8289C300846E11 /* gtest_repeat_test */, - 222ECC8F0E9EB33A00BEED94 /* gtest_sole_header_test */, - 3B238EDB0E8289C700846E11 /* gtest_stress_test */, - 222ECCA20E9EB47B00BEED94 /* gtest_test_part_test */, - 3B238E0F0E82887E00846E11 /* gtest-typed-test_test */, - 3B238EF30E8289CE00846E11 /* gtest_unittest */, - 3B238E1A0E82888500846E11 /* gtest_break_on_failure_unittest */, - 3B238E270E82888800846E11 /* gtest_color_test */, - 3B238E360E82889000846E11 /* gtest_env_var_test */, - 3B238E4E0E82889800846E11 /* gtest_filter_unittest */, - 3B238E5B0E82889B00846E11 /* gtest_list_tests_unittest */, - 3B238E9F0E82894D00846E11 /* gtest_output_test */, - 3B238F0A0E828A3800846E11 /* gtest_xml_outfile1_test_ */, - 3B238F150E828A3B00846E11 /* gtest_xml_outfile2_test_ */, - 40538A0A0ED71AF200AF209A /* gtest_xml_outfiles_test */, - 3B238F220E828A3D00846E11 /* gtest_xml_output_unittest */, - 3B238EE60E8289C900846E11 /* gtest_uninitialized_test */, - 3B238E850E82894800846E11 /* gtest_nc */, 40C44ADC0E3798F4008FCC51 /* Version Info */, - 408454310E96D39000AC66C2 /* Setup Python */, ); }; /* End PBXProject section */ @@ -2395,21 +613,12 @@ 404884AC0E2F7CD900CF7658 /* CHANGES in Resources */, 404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */, 404884AE0E2F7CD900CF7658 /* COPYING in Resources */, + 40C84978101A36540083642A /* libgtest_main.a in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXRezBuildPhase section */ - 8D07F2C50486CC7A007CD1D0 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXRezBuildPhase section */ - /* Begin PBXShellScriptBuildPhase section */ 3B238F5E0E828B5400846E11 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -2435,315 +644,62 @@ ); name = "Generate Version.h"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Version.h", + "$(PROJECT_TEMP_DIR)/Version.h", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $DERIVED_FILE_DIR\n"; + shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $PROJECT_TEMP_DIR"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 222ECC920E9EB33A00BEED94 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 40D2095B0E9FFBE500191629 /* gtest_sole_header_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 222ECCA50E9EB47B00BEED94 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 222ECCA60E9EB47B00BEED94 /* gtest-test-part_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 22A866040E70A39900F7AE6E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 22A866190E70A41000F7AE6E /* sample6_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238C640E81B8B500846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238D1D0E8283EA00846E11 /* gtest-death-test_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238D550E82855F00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238D640E8285C500846E11 /* gtest-filepath_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238D670E8285DA00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238D6E0E82860A00846E11 /* gtest-message_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238D770E82868F00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238D910E8286B800846E11 /* gtest-options_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E120E82887E00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F450E828AC300846E11 /* gtest-typed-test_test.cc in Sources */, - 408454BC0E97098200AC66C2 /* gtest-typed-test2_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E1D0E82888500846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F460E828AC800846E11 /* gtest_break_on_failure_unittest_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E2A0E82888800846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F470E828ACF00846E11 /* gtest_color_test_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E390E82889000846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F480E828AD500846E11 /* gtest_env_var_test_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E440E82889500846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F490E828ADA00846E11 /* gtest_environment_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E510E82889800846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F4A0E828ADF00846E11 /* gtest_filter_unittest_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E5E0E82889B00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F4B0E828AE700846E11 /* gtest_list_tests_unittest_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E7D0E82894300846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F4C0E828AEB00846E11 /* gtest_main_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E880E82894800846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F4D0E828AF000846E11 /* gtest_nc.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238E950E82894A00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F4E0E828AF400846E11 /* gtest_no_test_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EA20E82894D00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F4F0E828AFB00846E11 /* gtest_output_test_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EAF0E82894F00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F500E828B0000846E11 /* gtest_pred_impl_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238EC60E8289C100846E11 /* Sources */ = { + 40899F400FFA7184000B29AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3B238FF90E828C7E00846E11 /* production.cc in Sources */, - 3B238F510E828B0400846E11 /* gtest_prod_test.cc in Sources */, + 40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 3B238ED10E8289C300846E11 /* Sources */ = { + 4089A0100FFACEFC000B29AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3B238F520E828B0800846E11 /* gtest_repeat_test.cc in Sources */, + 4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */, + 4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 3B238EDE0E8289C700846E11 /* Sources */ = { + 40C848F7101A209C0083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 40D2095C0E9FFC0700191629 /* gtest_stress_test.cc in Sources */, + 40C848FF101A21150083642A /* gtest-all.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 3B238EE90E8289C900846E11 /* Sources */ = { + 40C84908101A217E0083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3B238F540E828B1700846E11 /* gtest_uninitialized_test_.cc in Sources */, + 40C84915101A21DF0083642A /* gtest_main.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 3B238EF60E8289CE00846E11 /* Sources */ = { + 40C8497F101A36850083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3B238F550E828B1F00846E11 /* gtest_unittest.cc in Sources */, + 40C84980101A36850083642A /* gtest_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 3B238F0D0E828A3800846E11 /* Sources */ = { + 40C8498E101A36A60083642A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3B238F560E828B2400846E11 /* gtest_xml_outfile1_test_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238F180E828A3B00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F570E828B2700846E11 /* gtest_xml_outfile2_test_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3B238F250E828A3D00846E11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3B238F580E828B2C00846E11 /* gtest_xml_output_unittest_.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 404885900E2F814C00CF7658 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 404885990E2F816100CF7658 /* sample1.cc in Sources */, - 4048859B0E2F816100CF7658 /* sample1_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 404885B30E2F82BA00CF7658 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 404885CF0E2F82F000CF7658 /* sample2.cc in Sources */, - 404885D00E2F82F000CF7658 /* sample2_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 404885D70E2F832A00CF7658 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 404886050E2F83DF00CF7658 /* sample3_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 404885E40E2F833000CF7658 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 404886080E2F840300CF7658 /* sample4.cc in Sources */, - 404886090E2F840300CF7658 /* sample4_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 404885F10E2F833400CF7658 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 404886140E2F849100CF7658 /* sample1.cc in Sources */, - 4048860C0E2F840E00CF7658 /* sample5_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9080EC27FBC00A70F4C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4539C91E0EC2800600A70F4C /* sample7_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9140EC27FC000A70F4C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4539C9200EC2801E00A70F4C /* sample8_unittest.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9500EC282D400A70F4C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4539C95C0EC2830E00A70F4C /* gtest-param-test2_test.cc in Sources */, - 4539C95D0EC2830E00A70F4C /* gtest-param-test_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9960EC283A800A70F4C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4539C9A10EC283E400A70F4C /* gtest-port_test.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4539C9A50EC2840700A70F4C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4539C9AF0EC2843000A70F4C /* gtest-linked_ptr_test.cc in Sources */, + 40C8498F101A36A60083642A /* sample1.cc in Sources */, + 40C84990101A36A60083642A /* sample1_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2751,1198 +707,81 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4048845F0E2F799B00CF7658 /* gtest-death-test.cc in Sources */, - 404884600E2F799B00CF7658 /* gtest-filepath.cc in Sources */, - 404884620E2F799B00CF7658 /* gtest-port.cc in Sources */, - 404884630E2F799B00CF7658 /* gtest.cc in Sources */, - 404884640E2F799B00CF7658 /* gtest_main.cc in Sources */, - 22A865FD0E70A35700F7AE6E /* gtest-typed-test.cc in Sources */, - 224A12A00E9EAD8F00BD17FD /* gtest-test-part.cc in Sources */, + 40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 222ECC900E9EB33A00BEED94 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 222ECC910E9EB33A00BEED94 /* PBXContainerItemProxy */; - }; - 222ECCA30E9EB47B00BEED94 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 222ECCA40E9EB47B00BEED94 /* PBXContainerItemProxy */; - }; - 22A866020E70A39900F7AE6E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 22A866030E70A39900F7AE6E /* PBXContainerItemProxy */; - }; - 22C44F370E9EB800004F2913 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 222ECC8F0E9EB33A00BEED94 /* gtest_sole_header_test */; - targetProxy = 22C44F360E9EB800004F2913 /* PBXContainerItemProxy */; - }; - 22C44F390E9EB808004F2913 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 222ECCA20E9EB47B00BEED94 /* gtest_test_part_test */; - targetProxy = 22C44F380E9EB808004F2913 /* PBXContainerItemProxy */; - }; - 3B238C990E81B92000846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238C980E81B92000846E11 /* PBXContainerItemProxy */; - }; - 3B238D530E82855F00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238D540E82855F00846E11 /* PBXContainerItemProxy */; - }; - 3B238D710E82862D00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238D700E82862D00846E11 /* PBXContainerItemProxy */; - }; - 3B238D7F0E82869400846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238D7E0E82869400846E11 /* PBXContainerItemProxy */; - }; - 3B238E100E82887E00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E110E82887E00846E11 /* PBXContainerItemProxy */; - }; - 3B238E1B0E82888500846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E1C0E82888500846E11 /* PBXContainerItemProxy */; - }; - 3B238E280E82888800846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E290E82888800846E11 /* PBXContainerItemProxy */; - }; - 3B238E370E82889000846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E380E82889000846E11 /* PBXContainerItemProxy */; - }; - 3B238E420E82889500846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E430E82889500846E11 /* PBXContainerItemProxy */; - }; - 3B238E4F0E82889800846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E500E82889800846E11 /* PBXContainerItemProxy */; - }; - 3B238E5C0E82889B00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E5D0E82889B00846E11 /* PBXContainerItemProxy */; - }; - 3B238E7B0E82894300846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E7C0E82894300846E11 /* PBXContainerItemProxy */; - }; - 3B238E860E82894800846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E870E82894800846E11 /* PBXContainerItemProxy */; - }; - 3B238E930E82894A00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238E940E82894A00846E11 /* PBXContainerItemProxy */; - }; - 3B238EA00E82894D00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238EA10E82894D00846E11 /* PBXContainerItemProxy */; - }; - 3B238EAD0E82894F00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238EAE0E82894F00846E11 /* PBXContainerItemProxy */; - }; - 3B238EC40E8289C100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238EC50E8289C100846E11 /* PBXContainerItemProxy */; - }; - 3B238ECF0E8289C300846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238ED00E8289C300846E11 /* PBXContainerItemProxy */; - }; - 3B238EDC0E8289C700846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238EDD0E8289C700846E11 /* PBXContainerItemProxy */; - }; - 3B238EE70E8289C900846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238EE80E8289C900846E11 /* PBXContainerItemProxy */; - }; - 3B238EF40E8289CE00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238EF50E8289CE00846E11 /* PBXContainerItemProxy */; - }; - 3B238F0B0E828A3800846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238F0C0E828A3800846E11 /* PBXContainerItemProxy */; - }; - 3B238F160E828A3B00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238F170E828A3B00846E11 /* PBXContainerItemProxy */; - }; - 3B238F230E828A3D00846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 3B238F240E828A3D00846E11 /* PBXContainerItemProxy */; - }; - 3B238F630E828B6100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 404885920E2F814C00CF7658 /* sample1_unittest */; - targetProxy = 3B238F620E828B6100846E11 /* PBXContainerItemProxy */; - }; - 3B238F650E828B6100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 404885B00E2F82BA00CF7658 /* sample2_unittest */; - targetProxy = 3B238F640E828B6100846E11 /* PBXContainerItemProxy */; - }; - 3B238F670E828B6100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 404885D40E2F832A00CF7658 /* sample3_unittest */; - targetProxy = 3B238F660E828B6100846E11 /* PBXContainerItemProxy */; - }; - 3B238F690E828B6100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 404885E10E2F833000CF7658 /* sample4_unittest */; - targetProxy = 3B238F680E828B6100846E11 /* PBXContainerItemProxy */; - }; - 3B238F6B0E828B6100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 404885EE0E2F833400CF7658 /* sample5_unittest */; - targetProxy = 3B238F6A0E828B6100846E11 /* PBXContainerItemProxy */; - }; - 3B238F6D0E828B6100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 22A866010E70A39900F7AE6E /* sample6_unittest */; - targetProxy = 3B238F6C0E828B6100846E11 /* PBXContainerItemProxy */; - }; - 3B238F6F0E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238C660E81B8B500846E11 /* gtest-death-test_test */; - targetProxy = 3B238F6E0E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F710E828B7100846E11 /* PBXTargetDependency */ = { + 40899F9D0FFA740F000B29AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 3B238D520E82855F00846E11 /* gtest-filepath_test */; - targetProxy = 3B238F700E828B7100846E11 /* PBXContainerItemProxy */; + target = 40899F420FFA7184000B29AE /* gtest_unittest-framework */; + targetProxy = 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */; }; - 3B238F730E828B7100846E11 /* PBXTargetDependency */ = { + 4089A0980FFAD34A000B29AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 3B238D690E8285DA00846E11 /* gtest-message_test */; - targetProxy = 3B238F720E828B7100846E11 /* PBXContainerItemProxy */; + target = 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */; + targetProxy = 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */; }; - 3B238F750E828B7100846E11 /* PBXTargetDependency */ = { + 408BEC101046CFE900DEF522 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 3B238D790E82868F00846E11 /* gtest-options_test */; - targetProxy = 3B238F740E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F790E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E0F0E82887E00846E11 /* gtest-typed-test_test */; - targetProxy = 3B238F780E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F810E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E410E82889500846E11 /* gtest_environment_test */; - targetProxy = 3B238F800E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F870E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E7A0E82894300846E11 /* gtest_main_unittest */; - targetProxy = 3B238F860E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F8B0E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E920E82894A00846E11 /* gtest_no_test_unittest */; - targetProxy = 3B238F8A0E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F8F0E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238EAC0E82894F00846E11 /* gtest_pred_impl_unittest */; - targetProxy = 3B238F8E0E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F910E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238EC30E8289C100846E11 /* gtest_prod_test */; - targetProxy = 3B238F900E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F930E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238ECE0E8289C300846E11 /* gtest_repeat_test */; - targetProxy = 3B238F920E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F950E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238EDB0E8289C700846E11 /* gtest_stress_test */; - targetProxy = 3B238F940E828B7100846E11 /* PBXContainerItemProxy */; - }; - 3B238F990E828B7100846E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238EF30E8289CE00846E11 /* gtest_unittest */; - targetProxy = 3B238F980E828B7100846E11 /* PBXContainerItemProxy */; - }; - 404885A80E2F824900CF7658 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 404885A70E2F824900CF7658 /* PBXContainerItemProxy */; - }; - 404885B10E2F82BA00CF7658 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 404885B20E2F82BA00CF7658 /* PBXContainerItemProxy */; - }; - 404885D50E2F832A00CF7658 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 404885D60E2F832A00CF7658 /* PBXContainerItemProxy */; - }; - 404885E20E2F833000CF7658 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 404885E30E2F833000CF7658 /* PBXContainerItemProxy */; - }; - 404885EF0E2F833400CF7658 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 404885F00E2F833400CF7658 /* PBXContainerItemProxy */; - }; - 40538A0B0ED71AF200AF209A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 40538A0C0ED71AF200AF209A /* PBXContainerItemProxy */; - }; - 40538A150ED71B1900AF209A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238F0A0E828A3800846E11 /* gtest_xml_outfile1_test_ */; - targetProxy = 40538A140ED71B1900AF209A /* PBXContainerItemProxy */; - }; - 40538A170ED71B1B00AF209A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238F150E828A3B00846E11 /* gtest_xml_outfile2_test_ */; - targetProxy = 40538A160ED71B1B00AF209A /* PBXContainerItemProxy */; - }; - 40538A450ED71D2200AF209A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 40538A0A0ED71AF200AF209A /* gtest_xml_outfiles_test */; - targetProxy = 40538A440ED71D2200AF209A /* PBXContainerItemProxy */; - }; - 4084546D0E96D70C00AC66C2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 4084546C0E96D70C00AC66C2 /* PBXContainerItemProxy */; - }; - 409A76540ED7393100E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 409A76530ED7393100E08B81 /* PBXContainerItemProxy */; - }; - 409A76580ED7393800E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 409A76570ED7393800E08B81 /* PBXContainerItemProxy */; - }; - 409A765C0ED7393D00E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 409A765B0ED7393D00E08B81 /* PBXContainerItemProxy */; - }; - 409A76600ED7394200E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 409A765F0ED7394200E08B81 /* PBXContainerItemProxy */; - }; - 409A76640ED7394500E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 409A76630ED7394500E08B81 /* PBXContainerItemProxy */; - }; - 409A76700ED7395000E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 409A766F0ED7395000E08B81 /* PBXContainerItemProxy */; - }; - 409A76740ED7395400E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 408454310E96D39000AC66C2 /* Setup Python */; - targetProxy = 409A76730ED7395400E08B81 /* PBXContainerItemProxy */; - }; - 409A76D00ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E1A0E82888500846E11 /* gtest_break_on_failure_unittest */; - targetProxy = 409A76CF0ED73CA300E08B81 /* PBXContainerItemProxy */; - }; - 409A76D20ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E270E82888800846E11 /* gtest_color_test */; - targetProxy = 409A76D10ED73CA300E08B81 /* PBXContainerItemProxy */; - }; - 409A76D40ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E360E82889000846E11 /* gtest_env_var_test */; - targetProxy = 409A76D30ED73CA300E08B81 /* PBXContainerItemProxy */; - }; - 409A76D60ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E4E0E82889800846E11 /* gtest_filter_unittest */; - targetProxy = 409A76D50ED73CA300E08B81 /* PBXContainerItemProxy */; - }; - 409A76D80ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E5B0E82889B00846E11 /* gtest_list_tests_unittest */; - targetProxy = 409A76D70ED73CA300E08B81 /* PBXContainerItemProxy */; - }; - 409A76DA0ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238E9F0E82894D00846E11 /* gtest_output_test */; - targetProxy = 409A76D90ED73CA300E08B81 /* PBXContainerItemProxy */; - }; - 409A76DC0ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238F220E828A3D00846E11 /* gtest_xml_output_unittest */; - targetProxy = 409A76DB0ED73CA300E08B81 /* PBXContainerItemProxy */; - }; - 409A76DE0ED73CA300E08B81 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3B238EE60E8289C900846E11 /* gtest_uninitialized_test */; - targetProxy = 409A76DD0ED73CA300E08B81 /* PBXContainerItemProxy */; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */; }; 40C44AE60E379922008FCC51 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 40C44ADC0E3798F4008FCC51 /* Version Info */; targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */; }; - 4539C9060EC27FBC00A70F4C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 4539C9070EC27FBC00A70F4C /* PBXContainerItemProxy */; - }; - 4539C9120EC27FC000A70F4C /* PBXTargetDependency */ = { + 40C8497B101A36850083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 4539C9130EC27FC000A70F4C /* PBXContainerItemProxy */; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8497C101A36850083642A /* PBXContainerItemProxy */; }; - 4539C94A0EC2823500A70F4C /* PBXTargetDependency */ = { + 40C8497D101A36850083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4539C9110EC27FC000A70F4C /* sample8_unittest */; - targetProxy = 4539C9490EC2823500A70F4C /* PBXContainerItemProxy */; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8497E101A36850083642A /* PBXContainerItemProxy */; }; - 4539C94C0EC2823500A70F4C /* PBXTargetDependency */ = { + 40C8498A101A36A60083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4539C9050EC27FBC00A70F4C /* sample7_unittest */; - targetProxy = 4539C94B0EC2823500A70F4C /* PBXContainerItemProxy */; + target = 40C848F9101A209C0083642A /* gtest-static */; + targetProxy = 40C8498B101A36A60083642A /* PBXContainerItemProxy */; }; - 4539C94E0EC282D400A70F4C /* PBXTargetDependency */ = { + 40C8498C101A36A60083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 4539C94F0EC282D400A70F4C /* PBXContainerItemProxy */; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8498D101A36A60083642A /* PBXContainerItemProxy */; }; - 4539C95F0EC2833100A70F4C /* PBXTargetDependency */ = { + 40C8499C101A36DC0083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4539C94D0EC282D400A70F4C /* gtest-param-test_test */; - targetProxy = 4539C95E0EC2833100A70F4C /* PBXContainerItemProxy */; + target = 40C8490A101A217E0083642A /* gtest_main-static */; + targetProxy = 40C8499B101A36DC0083642A /* PBXContainerItemProxy */; }; - 4539C9940EC283A800A70F4C /* PBXTargetDependency */ = { + 40C8499E101A36E50083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 4539C9950EC283A800A70F4C /* PBXContainerItemProxy */; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499D101A36E50083642A /* PBXContainerItemProxy */; }; - 4539C9A30EC2840700A70F4C /* PBXTargetDependency */ = { + 40C849A0101A36F10083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 8D07F2BC0486CC7A007CD1D0 /* gtest */; - targetProxy = 4539C9A40EC2840700A70F4C /* PBXContainerItemProxy */; + target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */; + targetProxy = 40C8499F101A36F10083642A /* PBXContainerItemProxy */; }; - 4539C9B10EC284C300A70F4C /* PBXTargetDependency */ = { + 40C849F7101A43440083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4539C9A20EC2840700A70F4C /* gtest-linked_ptr_test */; - targetProxy = 4539C9B00EC284C300A70F4C /* PBXContainerItemProxy */; + target = 40C8497A101A36850083642A /* gtest_unittest-static */; + targetProxy = 40C849F6101A43440083642A /* PBXContainerItemProxy */; }; - 4539C9B30EC284C300A70F4C /* PBXTargetDependency */ = { + 40C849F9101A43490083642A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4539C9930EC283A800A70F4C /* gtest-port_test */; - targetProxy = 4539C9B20EC284C300A70F4C /* PBXContainerItemProxy */; + target = 40C84989101A36A60083642A /* sample1_unittest-static */; + targetProxy = 40C849F8101A43490083642A /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 222ECC970E9EB33A00BEED94 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 222ECC980E9EB33A00BEED94 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 222ECCAA0E9EB47B00BEED94 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 222ECCAB0E9EB47B00BEED94 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 22A8660A0E70A39900F7AE6E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 22A8660B0E70A39900F7AE6E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238C690E81B8B500846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238C6A0E81B8B500846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238D5A0E82855F00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238D5B0E82855F00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238D6C0E8285DA00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238D6D0E8285DA00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238D7C0E82869000846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238D7D0E82869000846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E160E82887E00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E170E82887E00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E210E82888500846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E220E82888500846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E2E0E82888800846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E2F0E82888800846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E3D0E82889000846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E3E0E82889000846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E480E82889500846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E490E82889500846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E550E82889800846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E560E82889800846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E620E82889B00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E630E82889B00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E810E82894300846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E820E82894300846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E8C0E82894800846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E8D0E82894800846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238E990E82894A00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238E9A0E82894A00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238EA60E82894D00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238EA70E82894D00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238EB30E82894F00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238EB40E82894F00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238ECA0E8289C100846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238ECB0E8289C100846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238ED50E8289C300846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238ED60E8289C300846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238EE20E8289C700846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238EE30E8289C700846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238EED0E8289C900846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238EEE0E8289C900846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238EFA0E8289CE00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238EFB0E8289CE00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238F110E828A3800846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238F120E828A3800846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238F1C0E828A3B00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238F1D0E828A3B00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 3B238F290E828A3D00846E11 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 3B238F2A0E828A3D00846E11 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 409A75E10ED7380300E08B81 /* InternalPythonTestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; 3B238F600E828B5400846E11 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3964,178 +803,33 @@ }; name = Release; }; - 404885950E2F814C00CF7658 /* Debug */ = { + 40899F450FFA7185000B29AE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; }; name = Debug; }; - 404885960E2F814C00CF7658 /* Release */ = { + 40899F460FFA7185000B29AE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = "gtest_unittest-framework"; }; name = Release; }; - 404885B90E2F82BA00CF7658 /* Debug */ = { + 4089A0150FFACEFD000B29AE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + PRODUCT_NAME = "sample1_unittest-framework"; }; name = Debug; }; - 404885BA0E2F82BA00CF7658 /* Release */ = { + 4089A0160FFACEFD000B29AE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 404885DD0E2F832A00CF7658 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 404885DE0E2F832A00CF7658 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 404885EA0E2F833000CF7658 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 404885EB0E2F833000CF7658 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 404885F70E2F833400CF7658 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 404885F80E2F833400CF7658 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 40538A120ED71AF200AF209A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = gtest_output_test; - }; - name = Debug; - }; - 40538A130ED71AF200AF209A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PRODUCT_NAME = gtest_output_test; - ZERO_LINK = NO; - }; - name = Release; - }; - 408454320E96D39000AC66C2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 408454330E96D39000AC66C2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "sample1_unittest-framework"; }; name = Release; }; @@ -4155,143 +849,85 @@ }; name = Release; }; - 4539C90D0EC27FBC00A70F4C /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Debug; - }; - 4539C90E0EC27FBC00A70F4C /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; - }; - name = Release; - }; - 4539C9190EC27FC000A70F4C /* Debug */ = { + 40C848FB101A209D0083642A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + PRODUCT_NAME = gtest; }; name = Debug; }; - 4539C91A0EC27FC000A70F4C /* Release */ = { + 40C848FC101A209D0083642A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ( + ../, + ../include/, ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + PRODUCT_NAME = gtest; }; name = Release; }; - 4539C9560EC282D400A70F4C /* Debug */ = { + 40C8490E101A217F0083642A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + HEADER_SEARCH_PATHS = ( + ../, + ../include/, ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + PRODUCT_NAME = gtest_main; }; name = Debug; }; - 4539C9570EC282D400A70F4C /* Release */ = { + 40C8490F101A217F0083642A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; + baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + HEADER_SEARCH_PATHS = ( + ../, + ../include/, ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + PRODUCT_NAME = gtest_main; }; name = Release; }; - 4539C99C0EC283A800A70F4C /* Debug */ = { + 40C84985101A36850083642A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; }; name = Debug; }; - 4539C99D0EC283A800A70F4C /* Release */ = { + 40C84986101A36850083642A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + HEADER_SEARCH_PATHS = ../; + PRODUCT_NAME = gtest_unittest; }; name = Release; }; - 4539C9AA0EC2840700A70F4C /* Debug */ = { + 40C84995101A36A60083642A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + PRODUCT_NAME = "sample1_unittest-static"; }; name = Debug; }; - 4539C9AB0EC2840700A70F4C /* Release */ = { + 40C84996101A36A60083642A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\""; - FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\""; + PRODUCT_NAME = "sample1_unittest-static"; }; name = Release; }; @@ -4302,11 +938,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; HEADER_SEARCH_PATHS = ( - ../include/, ../, + ../include/, ); INFOPLIST_FILE = Resources/Info.plist; - INFOPLIST_PREFIX_HEADER = "$(DERIVED_FILE_DIR)/Version.h"; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; INFOPLIST_PREPROCESS = YES; PRODUCT_NAME = gtest; VERSIONING_SYSTEM = "apple-generic"; @@ -4320,11 +956,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; HEADER_SEARCH_PATHS = ( - ../include/, ../, + ../include/, ); INFOPLIST_FILE = Resources/Info.plist; - INFOPLIST_PREFIX_HEADER = "$(DERIVED_FILE_DIR)/Version.h"; + INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h"; INFOPLIST_PREPROCESS = YES; PRODUCT_NAME = gtest; VERSIONING_SYSTEM = "apple-generic"; @@ -4348,249 +984,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 222ECC960E9EB33A00BEED94 /* Build configuration list for PBXNativeTarget "gtest_sole_header_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 222ECC970E9EB33A00BEED94 /* Debug */, - 222ECC980E9EB33A00BEED94 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 222ECCA90E9EB47B00BEED94 /* Build configuration list for PBXNativeTarget "gtest_test_part_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 222ECCAA0E9EB47B00BEED94 /* Debug */, - 222ECCAB0E9EB47B00BEED94 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 22A866090E70A39900F7AE6E /* Build configuration list for PBXNativeTarget "sample6_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 22A8660A0E70A39900F7AE6E /* Debug */, - 22A8660B0E70A39900F7AE6E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238CD20E81B94000846E11 /* Build configuration list for PBXNativeTarget "gtest-death-test_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238C690E81B8B500846E11 /* Debug */, - 3B238C6A0E81B8B500846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238D590E82855F00846E11 /* Build configuration list for PBXNativeTarget "gtest-filepath_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238D5A0E82855F00846E11 /* Debug */, - 3B238D5B0E82855F00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238D6F0E82862800846E11 /* Build configuration list for PBXNativeTarget "gtest-message_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238D6C0E8285DA00846E11 /* Debug */, - 3B238D6D0E8285DA00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238D9D0E8286ED00846E11 /* Build configuration list for PBXNativeTarget "gtest-options_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238D7C0E82869000846E11 /* Debug */, - 3B238D7D0E82869000846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E150E82887E00846E11 /* Build configuration list for PBXNativeTarget "gtest-typed-test_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E160E82887E00846E11 /* Debug */, - 3B238E170E82887E00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E200E82888500846E11 /* Build configuration list for PBXNativeTarget "gtest_break_on_failure_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E210E82888500846E11 /* Debug */, - 3B238E220E82888500846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E2D0E82888800846E11 /* Build configuration list for PBXNativeTarget "gtest_color_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E2E0E82888800846E11 /* Debug */, - 3B238E2F0E82888800846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E3C0E82889000846E11 /* Build configuration list for PBXNativeTarget "gtest_env_var_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E3D0E82889000846E11 /* Debug */, - 3B238E3E0E82889000846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E470E82889500846E11 /* Build configuration list for PBXNativeTarget "gtest_environment_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E480E82889500846E11 /* Debug */, - 3B238E490E82889500846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E540E82889800846E11 /* Build configuration list for PBXNativeTarget "gtest_filter_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E550E82889800846E11 /* Debug */, - 3B238E560E82889800846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E610E82889B00846E11 /* Build configuration list for PBXNativeTarget "gtest_list_tests_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E620E82889B00846E11 /* Debug */, - 3B238E630E82889B00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E800E82894300846E11 /* Build configuration list for PBXNativeTarget "gtest_main_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E810E82894300846E11 /* Debug */, - 3B238E820E82894300846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E8B0E82894800846E11 /* Build configuration list for PBXNativeTarget "gtest_nc" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E8C0E82894800846E11 /* Debug */, - 3B238E8D0E82894800846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238E980E82894A00846E11 /* Build configuration list for PBXNativeTarget "gtest_no_test_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238E990E82894A00846E11 /* Debug */, - 3B238E9A0E82894A00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238EA50E82894D00846E11 /* Build configuration list for PBXNativeTarget "gtest_output_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238EA60E82894D00846E11 /* Debug */, - 3B238EA70E82894D00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238EB20E82894F00846E11 /* Build configuration list for PBXNativeTarget "gtest_pred_impl_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238EB30E82894F00846E11 /* Debug */, - 3B238EB40E82894F00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238EC90E8289C100846E11 /* Build configuration list for PBXNativeTarget "gtest_prod_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238ECA0E8289C100846E11 /* Debug */, - 3B238ECB0E8289C100846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238ED40E8289C300846E11 /* Build configuration list for PBXNativeTarget "gtest_repeat_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238ED50E8289C300846E11 /* Debug */, - 3B238ED60E8289C300846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238EE10E8289C700846E11 /* Build configuration list for PBXNativeTarget "gtest_stress_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238EE20E8289C700846E11 /* Debug */, - 3B238EE30E8289C700846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238EEC0E8289C900846E11 /* Build configuration list for PBXNativeTarget "gtest_uninitialized_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238EED0E8289C900846E11 /* Debug */, - 3B238EEE0E8289C900846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238EF90E8289CE00846E11 /* Build configuration list for PBXNativeTarget "gtest_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238EFA0E8289CE00846E11 /* Debug */, - 3B238EFB0E8289CE00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238F100E828A3800846E11 /* Build configuration list for PBXNativeTarget "gtest_xml_outfile1_test_" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238F110E828A3800846E11 /* Debug */, - 3B238F120E828A3800846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238F1B0E828A3B00846E11 /* Build configuration list for PBXNativeTarget "gtest_xml_outfile2_test_" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238F1C0E828A3B00846E11 /* Debug */, - 3B238F1D0E828A3B00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3B238F280E828A3D00846E11 /* Build configuration list for PBXNativeTarget "gtest_xml_output_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3B238F290E828A3D00846E11 /* Debug */, - 3B238F2A0E828A3D00846E11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -4600,65 +993,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4048859E0E2F818900CF7658 /* Build configuration list for PBXNativeTarget "sample1_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 404885950E2F814C00CF7658 /* Debug */, - 404885960E2F814C00CF7658 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 404885B80E2F82BA00CF7658 /* Build configuration list for PBXNativeTarget "sample2_unittest" */ = { + 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */ = { isa = XCConfigurationList; buildConfigurations = ( - 404885B90E2F82BA00CF7658 /* Debug */, - 404885BA0E2F82BA00CF7658 /* Release */, + 40899F450FFA7185000B29AE /* Debug */, + 40899F460FFA7185000B29AE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 404885DC0E2F832A00CF7658 /* Build configuration list for PBXNativeTarget "sample3_unittest" */ = { + 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */ = { isa = XCConfigurationList; buildConfigurations = ( - 404885DD0E2F832A00CF7658 /* Debug */, - 404885DE0E2F832A00CF7658 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 404885E90E2F833000CF7658 /* Build configuration list for PBXNativeTarget "sample4_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 404885EA0E2F833000CF7658 /* Debug */, - 404885EB0E2F833000CF7658 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 404885F60E2F833400CF7658 /* Build configuration list for PBXNativeTarget "sample5_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 404885F70E2F833400CF7658 /* Debug */, - 404885F80E2F833400CF7658 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 40538A110ED71AF200AF209A /* Build configuration list for PBXAggregateTarget "gtest_xml_outfiles_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 40538A120ED71AF200AF209A /* Debug */, - 40538A130ED71AF200AF209A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 408454340E96D3D400AC66C2 /* Build configuration list for PBXAggregateTarget "Setup Python" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 408454320E96D39000AC66C2 /* Debug */, - 408454330E96D39000AC66C2 /* Release */, + 4089A0150FFACEFD000B29AE /* Debug */, + 4089A0160FFACEFD000B29AE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -4672,52 +1020,43 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4539C90C0EC27FBC00A70F4C /* Build configuration list for PBXNativeTarget "sample7_unittest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4539C90D0EC27FBC00A70F4C /* Debug */, - 4539C90E0EC27FBC00A70F4C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 4539C9180EC27FC000A70F4C /* Build configuration list for PBXNativeTarget "sample8_unittest" */ = { + 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4539C9190EC27FC000A70F4C /* Debug */, - 4539C91A0EC27FC000A70F4C /* Release */, + 40C848FB101A209D0083642A /* Debug */, + 40C848FC101A209D0083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4539C9550EC282D400A70F4C /* Build configuration list for PBXNativeTarget "gtest-param-test_test" */ = { + 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4539C9560EC282D400A70F4C /* Debug */, - 4539C9570EC282D400A70F4C /* Release */, + 40C8490E101A217F0083642A /* Debug */, + 40C8490F101A217F0083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4539C99B0EC283A800A70F4C /* Build configuration list for PBXNativeTarget "gtest-port_test" */ = { + 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4539C99C0EC283A800A70F4C /* Debug */, - 4539C99D0EC283A800A70F4C /* Release */, + 40C84985101A36850083642A /* Debug */, + 40C84986101A36850083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4539C9A90EC2840700A70F4C /* Build configuration list for PBXNativeTarget "gtest-linked_ptr_test" */ = { + 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4539C9AA0EC2840700A70F4C /* Debug */, - 4539C9AB0EC2840700A70F4C /* Release */, + 40C84995101A36A60083642A /* Debug */, + 40C84996101A36A60083642A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest" */ = { + 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */ = { isa = XCConfigurationList; buildConfigurations = ( 4FADC24308B4156D00ABE55E /* Debug */, diff --git a/java/README.txt b/java/README.txt index 1656e59..3ed06a1 100644 --- a/java/README.txt +++ b/java/README.txt @@ -82,184 +82,11 @@ running unit tests. $ protoc --java_out=src/main/java -I../src \ ../src/google/protobuf/descriptor.proto + 3) Compile the code in src/main/java using whatever means you prefer. 4) Install the classes wherever you prefer. -Micro version -============================ - -The runtime and generated code for MICRO_RUNTIME is smaller -because it does not include support for the descriptor, -reflection or extensions. Also, not currently supported -are packed repeated elements nor testing of java_multiple_files. - -To create a jar file for the runtime and run tests invoke -"mvn package -P micro" from the <protobuf-root>/java -directory. The generated jar file is -<protobuf-root>java/target/protobuf-java-2.2.0-micro.jar. - -If you wish to compile the MICRO_RUTIME your self, place -the 7 files below, in <root>/com/google/protobuf and -create a jar file for use with your code and the generated -code: - -ByteStringMicro.java -CodedInputStreamMicro.java -CodedOutputStreamMicro.java -InvalidProtocolBufferException.java -MessageMicro.java -StringUtf8Micro.java -WireFormatMicro.java - -If you wish to change on the code generator it is located -in /src/google/protobuf/compiler/javamicro. - -To generate code for the MICRO_RUNTIME invoke protoc with ---javamicro_out command line parameter. javamciro_out takes -a series of optional sub-parameters separated by comma's -and a final parameter, with a colon separator, which defines -the source directory. Sub-paraemeters begin with a name -followed by an equal and if that sub-parameter has multiple -parameters they are seperated by "|". The command line options -are: - -opt -> speed or space -java_use_vector -> true or false -java_package -> <file-name>|<package-name> -java_outer_classname -> <file-name>|<package-name> - -opt: - This change the code generation to optimize for speed, - opt=speed, or space, opt=space. When opt=speed this - changes the code generation for strings to use - StringUtf8Micro which eliminates multiple conversions - of the string to utf8. The default value is opt=space. - -java_use_vector: - Is a boolean flag either java_use_vector=true or - java_use_vector=false. When java_use_vector=true the - code generated for repeated elements uses - java.util.Vector and when java_use_vector=false the - java.util.ArrayList<> is used. When java.util.Vector - is used the code must be compiled with Java 1.3 and - when ArrayList is used Java 1.5 or above must be used. - The using javac the source parameter maybe used to - control the version of the srouce: "javac -source 1.3". - You can also change the <source> xml element for the - maven-compiler-plugin. Below is for 1.5 sources: - - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>1.5</source> - <target>1.5</target> - </configuration> - </plugin> - - When compiling for 1.5 java_use_vector=false or not - present where the default value is false. - - And below would be for 1.3 sources note when changing - to 1.3 you must also set java_use_vector=true: - - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>1.3</source> - <target>1.5</target> - </configuration> - </plugin> - -java_package: - The allows setting/overriding the java_package option - and associates allows a package name for a file to - be specified on the command line. Overriding any - "option java_package xxxx" in the file. The default - if not present is to use the value from the package - statment or "option java_package xxxx" in the file. - -java_outer_classname: - This allows the setting/overriding of the outer - class name option and associates a class name - to a file. An outer class name is required and - must be specified if there are multiple messages - in a single proto file either in the proto source - file or on the command line. If not present the - no outer class name will be used. - -Below are a series of examples for clarification of the -various javamicro_out parameters using -src/test/proto/simple-data.proto: - -package testprotobuf; - -message SimpleData { - optional fixed64 id = 1; - optional string description = 2; - optional bool ok = 3 [default = false]; -}; - - -Assuming you've only compiled and not installed protoc and -your current working directory java/, then a simple -command line to compile simple-data would be: - -../src/protoc --javamicro_out=. src/test/proto/simple-data.proto - -This will create testprotobuf/SimpleData.java - -The directory testprotobuf is created because on line 1 -of simple-data.proto is "package testprotobuf;". If you -wanted a different package name you could use the -java_package option command line sub-parameter: - -../src/protoc '--javamicro_out=java_package=src/test/proto/simple-data.proto|my_package:.' src/test/proto/simple-data.proto - -Here you see the new java_package sub-parameter which -itself needs two parameters the file name and the -package name, these are separated by "|". Now you'll -find my_package/SimpleData.java. - -If you wanted to also change the optimization for -speed you'd add opt=speed with the comma seperator -as follows: - -../src/protoc '--javamicro_out=opt=speed,java_package=src/test/proto/simple-data.proto|my_package:.' src/test/proto/simple-data.proto - -Finally if you also wanted an outer class name you'd -do the following: - -../src/protoc '--javamicro_out=opt=speed,java_package=src/test/proto/simple-data.proto|my_package,java_outer_classname=src/test/proto/simple-data.proto|OuterName:.' src/test/proto/simple-data.proto - -Now you'll find my_packate/OuterName.java. - -As mentioned java_package and java_outer_classname -may also be specified in the file. In the example -below we must define java_outer_classname because -there are multiple messages in -src/test/proto/two-messages.proto - -package testmicroruntime; - -option java_package = "com.example"; -option java_outer_classname = "TestMessages"; - -message TestMessage1 { - required int32 id = 1; -} - -message TestMessage2 { - required int32 id = 1; -} - -This could be compiled using: - -../src/protoc --javamicro_out=. src/test/proto/two-message.proto - -With the result will be com/example/TestMessages.java - - Usage ===== diff --git a/java/pom.xml b/java/pom.xml index 5f7dd17..b07f29b 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -10,7 +10,7 @@ </parent> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> - <version>2.2.0</version> + <version>2.3.0</version> <packaging>jar</packaging> <name>Protocol Buffer Java API</name> <description> @@ -96,8 +96,6 @@ <configuration> <tasks> <mkdir dir="target/generated-test-sources" /> - <!--mkdir dir="target/generated-test-sources/opt-space" /--> - <!--mkdir dir="target/generated-test-sources/opt-speed" /--> <exec executable="../src/protoc"> <arg value="--java_out=target/generated-test-sources" /> <arg value="--proto_path=../src" /> @@ -115,21 +113,10 @@ <arg value="../src/google/protobuf/unittest_import_lite.proto" /> <arg value="../src/google/protobuf/unittest_lite_imports_nonlite.proto" /> <arg value="../src/google/protobuf/unittest_enormous_descriptor.proto" /> - </exec> - <exec executable="../src/protoc"> - <arg value="--javamicro_out=opt=speed,java_use_vector=false,java_package=google/protobuf/unittest_import_micro.proto|com.google.protobuf.micro,java_outer_classname=google/protobuf/unittest_import_micro.proto|UnittestImportMicro:target/generated-test-sources" /> - <arg value="--proto_path=../src" /> - <arg value="--proto_path=src/test/java" /> - <arg value="../src/google/protobuf/unittest_micro.proto" /> - <arg value="../src/google/protobuf/unittest_simple_micro.proto" /> - <arg value="../src/google/protobuf/unittest_stringutf8_micro.proto" /> - <arg value="../src/google/protobuf/unittest_recursive_micro.proto" /> - <arg value="../src/google/protobuf/unittest_import_micro.proto" /> + <arg value="../src/google/protobuf/unittest_no_generic_services.proto" /> </exec> </tasks> <testSourceRoot>target/generated-test-sources</testSourceRoot> - <!--testSourceRoot>target/generated-test-sources/opt-space</testSourceRoot--> - <!--testSourceRoot>target/generated-test-sources/opt-speed</testSourceRoot--> </configuration> <goals> <goal>run</goal> @@ -184,48 +171,5 @@ </plugins> </build> </profile> - <profile> - <id>micro</id> - <build> - <plugins> - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <includes> - <include>**/MessageMicro.java</include> - <include>**/ByteStringMicro.java</include> - <include>**/CodedInputStreamMicro.java</include> - <include>**/CodedOutputStreamMicro.java</include> - <include>**/InvalidProtocolBufferMicroException.java</include> - <include>**/StringUtf8Micro.java</include> - <include>**/WireFormatMicro.java</include> - </includes> - <testIncludes> - <testInclude>**/MicroTest.java</testInclude> - <testInclude>**/MicroOuterClass.java</testInclude> - <testInclude>**/SimpleMessageMicro.java</testInclude> - <testInclude>**/StringUtf8.java</testInclude> - <testInclude>**/RecursiveMessageMicro.java</testInclude> - <testInclude>**/UnittestImportMicro.java</testInclude> - </testIncludes> - </configuration> - </plugin> - <plugin> - <artifactId>maven-surefire-plugin</artifactId> - <configuration> - <includes> - <include>**/MicroTest.java</include> - </includes> - </configuration> - </plugin> - <plugin> - <artifactId>maven-jar-plugin</artifactId> - <configuration> - <classifier>micro</classifier> - </configuration> - </plugin> - </plugins> - </build> - </profile> </profiles> </project> diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/src/main/java/com/google/protobuf/AbstractMessage.java index e5bdefe..b059bc9 100644 --- a/java/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/src/main/java/com/google/protobuf/AbstractMessage.java @@ -311,6 +311,12 @@ public abstract class AbstractMessage extends AbstractMessageLite } else { field = extension.descriptor; defaultInstance = extension.defaultInstance; + if (defaultInstance == null && + field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + throw new IllegalStateException( + "Message-typed extension lacked default instance: " + + field.getFullName()); + } } } else { field = null; @@ -319,15 +325,28 @@ public abstract class AbstractMessage extends AbstractMessageLite field = type.findFieldByNumber(fieldNumber); } - if (field == null || wireType != - FieldSet.getWireFormatForFieldType( - field.getLiteType(), - field.getOptions().getPacked())) { - // Unknown field or wrong wire type. Skip. + boolean unknown = false; + boolean packed = false; + if (field == null) { + unknown = true; // Unknown field. + } else if (wireType == FieldSet.getWireFormatForFieldType( + field.getLiteType(), + false /* isPacked */)) { + packed = false; + } else if (field.isPackable() && + wireType == FieldSet.getWireFormatForFieldType( + field.getLiteType(), + true /* isPacked */)) { + packed = true; + } else { + unknown = true; // Unknown wire type. + } + + if (unknown) { // Unknown field or wrong wire type. Skip. return unknownFields.mergeFieldFrom(tag, input); } - if (field.getOptions().getPacked()) { + if (packed) { final int length = input.readRawVarint32(); final int limit = input.pushLimit(length); if (field.getLiteType() == WireFormat.FieldType.ENUM) { @@ -673,13 +692,13 @@ public abstract class AbstractMessage extends AbstractMessageLite } @Override - public BuilderType mergeDelimitedFrom(final InputStream input) + public boolean mergeDelimitedFrom(final InputStream input) throws IOException { return super.mergeDelimitedFrom(input); } @Override - public BuilderType mergeDelimitedFrom( + public boolean mergeDelimitedFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException { diff --git a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java index 489577d..9210d85 100644 --- a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java +++ b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java @@ -72,14 +72,21 @@ public abstract class AbstractMessageLite implements MessageLite { } public void writeTo(final OutputStream output) throws IOException { - final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); + final int bufferSize = + CodedOutputStream.computePreferredBufferSize(getSerializedSize()); + final CodedOutputStream codedOutput = + CodedOutputStream.newInstance(output, bufferSize); writeTo(codedOutput); codedOutput.flush(); } public void writeDelimitedTo(final OutputStream output) throws IOException { - final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); - codedOutput.writeRawVarint32(getSerializedSize()); + final int serialized = getSerializedSize(); + final int bufferSize = CodedOutputStream.computePreferredBufferSize( + CodedOutputStream.computeRawVarint32Size(serialized) + serialized); + final CodedOutputStream codedOutput = + CodedOutputStream.newInstance(output, bufferSize); + codedOutput.writeRawVarint32(serialized); writeTo(codedOutput); codedOutput.flush(); } @@ -98,13 +105,7 @@ public abstract class AbstractMessageLite implements MessageLite { public BuilderType mergeFrom(final CodedInputStream input) throws IOException { - // TODO(kenton): Don't use null here. Currently we have to because - // using ExtensionRegistry.getEmptyRegistry() would imply a dependency - // on ExtensionRegistry. However, AbstractMessage overrides this with - // a correct implementation, and lite messages don't yet support - // extensions, so it ends up not mattering for now. It will matter - // once lite messages support extensions. - return mergeFrom(input, null); + return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry()); } // Re-defined here for return type covariance. @@ -268,20 +269,24 @@ public abstract class AbstractMessageLite implements MessageLite { } } - public BuilderType mergeDelimitedFrom( + public boolean mergeDelimitedFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException { - final int size = CodedInputStream.readRawVarint32(input); + final int firstByte = input.read(); + if (firstByte == -1) { + return false; + } + final int size = CodedInputStream.readRawVarint32(firstByte, input); final InputStream limitedInput = new LimitedInputStream(input, size); - return mergeFrom(limitedInput, extensionRegistry); + mergeFrom(limitedInput, extensionRegistry); + return true; } - public BuilderType mergeDelimitedFrom(final InputStream input) + public boolean mergeDelimitedFrom(final InputStream input) throws IOException { - final int size = CodedInputStream.readRawVarint32(input); - final InputStream limitedInput = new LimitedInputStream(input, size); - return mergeFrom(limitedInput); + return mergeDelimitedFrom(input, + ExtensionRegistryLite.getEmptyRegistry()); } /** diff --git a/java/src/main/java/com/google/protobuf/ByteString.java b/java/src/main/java/com/google/protobuf/ByteString.java index c83c335..5fade03 100644 --- a/java/src/main/java/com/google/protobuf/ByteString.java +++ b/java/src/main/java/com/google/protobuf/ByteString.java @@ -36,6 +36,7 @@ import java.io.ByteArrayOutputStream; import java.io.FilterOutputStream; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; +import java.util.List; /** * Immutable array of bytes. @@ -99,6 +100,24 @@ public final class ByteString { } /** + * Copies {@code size} bytes from a {@code java.nio.ByteBuffer} into + * a {@code ByteString}. + */ + public static ByteString copyFrom(final ByteBuffer bytes, final int size) { + final byte[] copy = new byte[size]; + bytes.get(copy); + return new ByteString(copy); + } + + /** + * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into + * a {@code ByteString}. + */ + public static ByteString copyFrom(final ByteBuffer bytes) { + return copyFrom(bytes, bytes.remaining()); + } + + /** * Encodes {@code text} into a sequence of bytes using the named charset * and returns the result as a {@code ByteString}. */ @@ -119,6 +138,34 @@ public final class ByteString { } } + /** + * Concatenates all byte strings in the list and returns the result. + * + * <p>The returned {@code ByteString} is not necessarily a unique object. + * If the list is empty, the returned object is the singleton empty + * {@code ByteString}. If the list has only one element, that + * {@code ByteString} will be returned without copying. + */ + public static ByteString copyFrom(List<ByteString> list) { + if (list.size() == 0) { + return EMPTY; + } else if (list.size() == 1) { + return list.get(0); + } + + int size = 0; + for (ByteString str : list) { + size += str.size(); + } + byte[] bytes = new byte[size]; + int pos = 0; + for (ByteString str : list) { + System.arraycopy(str.bytes, 0, bytes, pos, str.size()); + pos += str.size(); + } + return new ByteString(bytes); + } + // ================================================================= // ByteString -> byte[] diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/src/main/java/com/google/protobuf/CodedInputStream.java index 9125957..ad43f96 100644 --- a/java/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/src/main/java/com/google/protobuf/CodedInputStream.java @@ -84,8 +84,9 @@ public final class CodedInputStream { } lastTag = readRawVarint32(); - if (lastTag == 0) { - // If we actually read zero, that's not a valid tag. + if (WireFormat.getTagFieldNumber(lastTag) == 0) { + // If we actually read zero (or any tag number corresponding to field + // number zero), that's not a valid tag. throw InvalidProtocolBufferException.invalidTag(); } return lastTag; @@ -355,8 +356,26 @@ public final class CodedInputStream { * CodedInputStream buffers its input. */ static int readRawVarint32(final InputStream input) throws IOException { - int result = 0; - int offset = 0; + final int firstByte = input.read(); + if (firstByte == -1) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + return readRawVarint32(firstByte, input); + } + + /** + * Like {@link #readRawVarint32(InputStream)}, but expects that the caller + * has already read one byte. This allows the caller to determine if EOF + * has been reached before attempting to read. + */ + static int readRawVarint32(final int firstByte, + final InputStream input) throws IOException { + if ((firstByte & 0x80) == 0) { + return firstByte; + } + + int result = firstByte & 0x7f; + int offset = 7; for (; offset < 32; offset += 7) { final int b = input.read(); if (b == -1) { @@ -467,7 +486,9 @@ public final class CodedInputStream { /** * The total number of bytes read before the current buffer. The total * bytes read up to the current position can be computed as - * {@code totalBytesRetired + bufferPos}. + * {@code totalBytesRetired + bufferPos}. This value may be negative if + * reading started in the middle of the current buffer (e.g. if the + * constructor that takes a byte array and an offset was used). */ private int totalBytesRetired; @@ -489,6 +510,7 @@ public final class CodedInputStream { this.buffer = buffer; bufferSize = off + len; bufferPos = off; + totalBytesRetired = -off; input = null; } @@ -496,6 +518,7 @@ public final class CodedInputStream { buffer = new byte[BUFFER_SIZE]; bufferSize = 0; bufferPos = 0; + totalBytesRetired = 0; this.input = input; } @@ -546,13 +569,21 @@ public final class CodedInputStream { * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). */ public void resetSizeCounter() { - totalBytesRetired = 0; + totalBytesRetired = -bufferPos; } /** * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This * is called when descending into a length-delimited embedded message. * + * <p>Note that {@code pushLimit()} does NOT affect how many bytes the + * {@code CodedInputStream} reads from an underlying {@code InputStream} when + * refreshing its buffer. If you need to prevent reading past a certain + * point in the underlying {@code InputStream} (e.g. because you expect it to + * contain more data after the end of the message which you need to handle + * differently) then you must place a wrapper around you {@code InputStream} + * which limits the amount of data that can be read from it. + * * @return the old limit. */ public int pushLimit(int byteLimit) throws InvalidProtocolBufferException { @@ -616,6 +647,14 @@ public final class CodedInputStream { } /** + * The total bytes read up to the current position. Calling + * {@link #resetSizeCounter()} resets this value to zero. + */ + public int getTotalBytesRead() { + return totalBytesRetired + bufferPos; + } + + /** * Called with {@code this.buffer} is empty to read more bytes from the * input. If {@code mustSucceed} is true, refillBuffer() gurantees that * either there will be at least one byte in the buffer when it returns diff --git a/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/src/main/java/com/google/protobuf/CodedOutputStream.java index d3907a7..58dd150 100644 --- a/java/src/main/java/com/google/protobuf/CodedOutputStream.java +++ b/java/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -60,6 +60,18 @@ public final class CodedOutputStream { */ public static final int DEFAULT_BUFFER_SIZE = 4096; + /** + * Returns the buffer size to efficiently write dataLength bytes to this + * CodedOutputStream. Used by AbstractMessageLite. + * + * @return the buffer size to efficiently write dataLength bytes to this + * CodedOutputStream. + */ + static int computePreferredBufferSize(int dataLength) { + if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE; + return dataLength; + } + private CodedOutputStream(final byte[] buffer, final int offset, final int length) { output = null; diff --git a/java/src/main/java/com/google/protobuf/Descriptors.java b/java/src/main/java/com/google/protobuf/Descriptors.java index 0c162d5..c5e9a04 100644 --- a/java/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/src/main/java/com/google/protobuf/Descriptors.java @@ -48,7 +48,7 @@ import java.io.UnsupportedEncodingException; * (given a message object of the type) {@code message.getDescriptorForType()}. * * Descriptors are built from DescriptorProtos, as defined in - * {@code net/proto2/proto/descriptor.proto}. + * {@code google/protobuf/descriptor.proto}. * * @author kenton@google.com Kenton Varda */ @@ -699,6 +699,11 @@ public final class Descriptors { return getOptions().getPacked(); } + /** Can this field be packed? i.e. is it a repeated primitive field? */ + public boolean isPackable() { + return isRepeated() && getLiteType().isPackable(); + } + /** Returns true if the field had an explicitly-defined default value. */ public boolean hasDefaultValue() { return proto.hasDefaultValue(); } @@ -810,39 +815,34 @@ public final class Descriptors { private Object defaultValue; public enum Type { - DOUBLE (FieldDescriptorProto.Type.TYPE_DOUBLE , JavaType.DOUBLE ), - FLOAT (FieldDescriptorProto.Type.TYPE_FLOAT , JavaType.FLOAT ), - INT64 (FieldDescriptorProto.Type.TYPE_INT64 , JavaType.LONG ), - UINT64 (FieldDescriptorProto.Type.TYPE_UINT64 , JavaType.LONG ), - INT32 (FieldDescriptorProto.Type.TYPE_INT32 , JavaType.INT ), - FIXED64 (FieldDescriptorProto.Type.TYPE_FIXED64 , JavaType.LONG ), - FIXED32 (FieldDescriptorProto.Type.TYPE_FIXED32 , JavaType.INT ), - BOOL (FieldDescriptorProto.Type.TYPE_BOOL , JavaType.BOOLEAN ), - STRING (FieldDescriptorProto.Type.TYPE_STRING , JavaType.STRING ), - GROUP (FieldDescriptorProto.Type.TYPE_GROUP , JavaType.MESSAGE ), - MESSAGE (FieldDescriptorProto.Type.TYPE_MESSAGE , JavaType.MESSAGE ), - BYTES (FieldDescriptorProto.Type.TYPE_BYTES , JavaType.BYTE_STRING), - UINT32 (FieldDescriptorProto.Type.TYPE_UINT32 , JavaType.INT ), - ENUM (FieldDescriptorProto.Type.TYPE_ENUM , JavaType.ENUM ), - SFIXED32(FieldDescriptorProto.Type.TYPE_SFIXED32, JavaType.INT ), - SFIXED64(FieldDescriptorProto.Type.TYPE_SFIXED64, JavaType.LONG ), - SINT32 (FieldDescriptorProto.Type.TYPE_SINT32 , JavaType.INT ), - SINT64 (FieldDescriptorProto.Type.TYPE_SINT64 , JavaType.LONG ); - - Type(final FieldDescriptorProto.Type proto, final JavaType javaType) { - this.proto = proto; + DOUBLE (JavaType.DOUBLE ), + FLOAT (JavaType.FLOAT ), + INT64 (JavaType.LONG ), + UINT64 (JavaType.LONG ), + INT32 (JavaType.INT ), + FIXED64 (JavaType.LONG ), + FIXED32 (JavaType.INT ), + BOOL (JavaType.BOOLEAN ), + STRING (JavaType.STRING ), + GROUP (JavaType.MESSAGE ), + MESSAGE (JavaType.MESSAGE ), + BYTES (JavaType.BYTE_STRING), + UINT32 (JavaType.INT ), + ENUM (JavaType.ENUM ), + SFIXED32(JavaType.INT ), + SFIXED64(JavaType.LONG ), + SINT32 (JavaType.INT ), + SINT64 (JavaType.LONG ); + + Type(final JavaType javaType) { this.javaType = javaType; - - if (ordinal() != proto.getNumber() - 1) { - throw new RuntimeException( - "descriptor.proto changed but Desrciptors.java wasn't updated."); - } } - private FieldDescriptorProto.Type proto; private JavaType javaType; - public FieldDescriptorProto.Type toProto() { return proto; } + public FieldDescriptorProto.Type toProto() { + return FieldDescriptorProto.Type.valueOf(ordinal() + 1); + } public JavaType getJavaType() { return javaType; } public static Type valueOf(final FieldDescriptorProto.Type type) { @@ -902,16 +902,10 @@ public final class Descriptors { } // Only repeated primitive fields may be packed. - if (proto.getOptions().getPacked()) { - if (proto.getLabel() != FieldDescriptorProto.Label.LABEL_REPEATED || - proto.getType() == FieldDescriptorProto.Type.TYPE_STRING || - proto.getType() == FieldDescriptorProto.Type.TYPE_GROUP || - proto.getType() == FieldDescriptorProto.Type.TYPE_MESSAGE || - proto.getType() == FieldDescriptorProto.Type.TYPE_BYTES) { - throw new DescriptorValidationException(this, - "[packed = true] can only be specified for repeated primitive " + - "fields."); - } + if (proto.getOptions().getPacked() && !isPackable()) { + throw new DescriptorValidationException(this, + "[packed = true] can only be specified for repeated primitive " + + "fields."); } if (isExtension) { @@ -1030,10 +1024,26 @@ public final class Descriptors { defaultValue = TextFormat.parseUInt64(proto.getDefaultValue()); break; case FLOAT: - defaultValue = Float.valueOf(proto.getDefaultValue()); + if (proto.getDefaultValue().equals("inf")) { + defaultValue = Float.POSITIVE_INFINITY; + } else if (proto.getDefaultValue().equals("-inf")) { + defaultValue = Float.NEGATIVE_INFINITY; + } else if (proto.getDefaultValue().equals("nan")) { + defaultValue = Float.NaN; + } else { + defaultValue = Float.valueOf(proto.getDefaultValue()); + } break; case DOUBLE: - defaultValue = Double.valueOf(proto.getDefaultValue()); + if (proto.getDefaultValue().equals("inf")) { + defaultValue = Double.POSITIVE_INFINITY; + } else if (proto.getDefaultValue().equals("-inf")) { + defaultValue = Double.NEGATIVE_INFINITY; + } else if (proto.getDefaultValue().equals("nan")) { + defaultValue = Double.NaN; + } else { + defaultValue = Double.valueOf(proto.getDefaultValue()); + } break; case BOOL: defaultValue = Boolean.valueOf(proto.getDefaultValue()); @@ -1064,12 +1074,9 @@ public final class Descriptors { "Message type had default value."); } } catch (NumberFormatException e) { - final DescriptorValidationException validationException = - new DescriptorValidationException(this, - "Could not parse default value: \"" + - proto.getDefaultValue() + '\"'); - validationException.initCause(e); - throw validationException; + throw new DescriptorValidationException(this, + "Could not parse default value: \"" + + proto.getDefaultValue() + '\"', e); } } else { // Determine the default default for this field. @@ -1536,14 +1543,7 @@ public final class Descriptors { private DescriptorValidationException( final GenericDescriptor problemDescriptor, final String description) { - this(problemDescriptor, description, null); - } - - private DescriptorValidationException( - final GenericDescriptor problemDescriptor, - final String description, - final Throwable cause) { - super(problemDescriptor.getFullName() + ": " + description, cause); + super(problemDescriptor.getFullName() + ": " + description); // Note that problemDescriptor may be partially uninitialized, so we // don't want to expose it directly to the user. So, we only provide @@ -1554,6 +1554,14 @@ public final class Descriptors { } private DescriptorValidationException( + final GenericDescriptor problemDescriptor, + final String description, + final Throwable cause) { + this(problemDescriptor, description); + initCause(cause); + } + + private DescriptorValidationException( final FileDescriptor problemDescriptor, final String description) { super(problemDescriptor.getName() + ": " + description); diff --git a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java index 87bbd6e..d4f6ba9 100644 --- a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java +++ b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java @@ -157,6 +157,11 @@ public final class ExtensionRegistry extends ExtensionRegistryLite { public void add(final GeneratedMessage.GeneratedExtension<?, ?> extension) { if (extension.getDescriptor().getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (extension.getMessageDefaultInstance() == null) { + throw new IllegalStateException( + "Registered message-type extension had null default instance: " + + extension.getDescriptor().getFullName()); + } add(new ExtensionInfo(extension.getDescriptor(), extension.getMessageDefaultInstance())); } else { diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/src/main/java/com/google/protobuf/GeneratedMessage.java index 4994faa..dba0ec8 100644 --- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java +++ b/java/src/main/java/com/google/protobuf/GeneratedMessage.java @@ -352,7 +352,10 @@ public abstract class GeneratedMessage extends AbstractMessage { FieldDescriptor descriptor = extension.getDescriptor(); final Object value = extensions.getField(descriptor); if (value == null) { - if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (descriptor.isRepeated()) { + return (Type) Collections.emptyList(); + } else if (descriptor.getJavaType() == + FieldDescriptor.JavaType.MESSAGE) { return (Type) extension.getMessageDefaultInstance(); } else { return (Type) extension.fromReflectionType( @@ -721,25 +724,8 @@ public abstract class GeneratedMessage extends AbstractMessage { /** For use by generated code only. */ public static <ContainingType extends Message, Type> GeneratedExtension<ContainingType, Type> - newGeneratedExtension(final FieldDescriptor descriptor, - final Class<Type> type) { - if (descriptor.isRepeated()) { - throw new IllegalArgumentException( - "Must call newRepeatedGeneratedExtension() for repeated types."); - } - return new GeneratedExtension<ContainingType, Type>(descriptor, type); - } - - /** For use by generated code only. */ - public static <ContainingType extends Message, Type> - GeneratedExtension<ContainingType, List<Type>> - newRepeatedGeneratedExtension( - final FieldDescriptor descriptor, final Class<Type> type) { - if (!descriptor.isRepeated()) { - throw new IllegalArgumentException( - "Must call newGeneratedExtension() for non-repeated types."); - } - return new GeneratedExtension<ContainingType, List<Type>>(descriptor, type); + newGeneratedExtension() { + return new GeneratedExtension<ContainingType, Type>(); } /** @@ -772,8 +758,23 @@ public abstract class GeneratedMessage extends AbstractMessage { // TODO(kenton): Find ways to avoid using Java reflection within this // class. Also try to avoid suppressing unchecked warnings. - private GeneratedExtension(final FieldDescriptor descriptor, - final Class type) { + // We can't always initialize a GeneratedExtension when we first construct + // it due to initialization order difficulties (namely, the descriptor may + // not have been constructed yet, since it is often constructed by the + // initializer of a separate module). So, we construct an uninitialized + // GeneratedExtension once, then call internalInit() on it later. Generated + // code will always call internalInit() on all extensions as part of the + // static initialization code, and internalInit() throws an exception if + // called more than once, so this method is useless to users. + private GeneratedExtension() {} + + /** For use by generated code only. */ + public void internalInit(final FieldDescriptor descriptor, + final Class type) { + if (this.descriptor != null) { + throw new IllegalStateException("Already initialized."); + } + if (!descriptor.isExtension()) { throw new IllegalArgumentException( "GeneratedExtension given a regular (non-extension) field."); @@ -789,6 +790,10 @@ public abstract class GeneratedMessage extends AbstractMessage { messageDefaultInstance = (Message) invokeOrDie(getMethodOrDie(type, "getDefaultInstance"), null); + if (messageDefaultInstance == null) { + throw new IllegalStateException( + type.getName() + ".getDefaultInstance() returned null."); + } break; case ENUM: enumValueOf = getMethodOrDie(type, "valueOf", @@ -804,11 +809,11 @@ public abstract class GeneratedMessage extends AbstractMessage { } } - private final FieldDescriptor descriptor; - private final Class type; - private final Method enumValueOf; - private final Method enumGetValueDescriptor; - private final Message messageDefaultInstance; + private FieldDescriptor descriptor; + private Class type; + private Method enumValueOf; + private Method enumGetValueDescriptor; + private Message messageDefaultInstance; public FieldDescriptor getDescriptor() { return descriptor; } diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java index c68414b..9cdd4e9 100644 --- a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -303,7 +303,7 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { final ExtensionRegistryLite extensionRegistry, final int tag) throws IOException { final FieldSet<ExtensionDescriptor> extensions = - internalGetResult().extensions; + ((ExtendableMessage) internalGetResult()).extensions; final int wireType = WireFormat.getTagWireType(tag); final int fieldNumber = WireFormat.getTagFieldNumber(tag); @@ -312,15 +312,29 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { extensionRegistry.findLiteExtensionByNumber( getDefaultInstanceForType(), fieldNumber); - if (extension == null || wireType != - FieldSet.getWireFormatForFieldType( - extension.descriptor.getLiteType(), - extension.descriptor.isPacked())) { - // Unknown field or wrong wire type. Skip. + boolean unknown = false; + boolean packed = false; + if (extension == null) { + unknown = true; // Unknown field. + } else if (wireType == FieldSet.getWireFormatForFieldType( + extension.descriptor.getLiteType(), + false /* isPacked */)) { + packed = false; // Normal, unpacked value. + } else if (extension.descriptor.isRepeated && + extension.descriptor.type.isPackable() && + wireType == FieldSet.getWireFormatForFieldType( + extension.descriptor.getLiteType(), + true /* isPacked */)) { + packed = true; // Packed value. + } else { + unknown = true; // Wrong wire type. + } + + if (unknown) { // Unknown field or wrong wire type. Skip. return input.skipField(tag); } - if (extension.descriptor.isPacked()) { + if (packed) { final int length = input.readRawVarint32(); final int limit = input.pushLimit(length); if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { @@ -396,7 +410,8 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { } protected final void mergeExtensionFields(final MessageType other) { - internalGetResult().extensions.mergeFrom(other.extensions); + ((ExtendableMessage) internalGetResult()).extensions.mergeFrom( + ((ExtendableMessage) other).extensions); } } @@ -405,34 +420,8 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { /** For use by generated code only. */ public static <ContainingType extends MessageLite, Type> GeneratedExtension<ContainingType, Type> - newGeneratedExtension( - final ContainingType containingTypeDefaultInstance, - final Type defaultValue, - final MessageLite messageDefaultInstance, - final Internal.EnumLiteMap<?> enumTypeMap, - final int number, - final WireFormat.FieldType type) { - return new GeneratedExtension<ContainingType, Type>( - containingTypeDefaultInstance, defaultValue, messageDefaultInstance, - new ExtensionDescriptor(enumTypeMap, number, type, - false /* isRepeated */, false /* isPacked */)); - } - - /** For use by generated code only. */ - public static <ContainingType extends MessageLite, Type> - GeneratedExtension<ContainingType, List<Type>> - newRepeatedGeneratedExtension( - final ContainingType containingTypeDefaultInstance, - final MessageLite messageDefaultInstance, - final Internal.EnumLiteMap<?> enumTypeMap, - final int number, - final WireFormat.FieldType type, - final boolean isPacked) { - return new GeneratedExtension<ContainingType, List<Type>>( - containingTypeDefaultInstance, Collections.<Type>emptyList(), - messageDefaultInstance, - new ExtensionDescriptor( - enumTypeMap, number, type, true /* isRepeated */, isPacked)); + newGeneratedExtension() { + return new GeneratedExtension<ContainingType, Type>(); } private static final class ExtensionDescriptor @@ -500,7 +489,16 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { */ public static final class GeneratedExtension< ContainingType extends MessageLite, Type> { - private GeneratedExtension( + // We can't always initialize a GeneratedExtension when we first construct + // it due to initialization order difficulties (namely, the default + // instances may not have been constructed yet). So, we construct an + // uninitialized GeneratedExtension once, then call internalInit() on it + // later. Generated code will always call internalInit() on all extensions + // as part of the static initialization code, and internalInit() throws an + // exception if called more than once, so this method is useless to users. + private GeneratedExtension() {} + + private void internalInit( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, @@ -511,10 +509,39 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { this.descriptor = descriptor; } - private final ContainingType containingTypeDefaultInstance; - private final Type defaultValue; - private final MessageLite messageDefaultInstance; - private final ExtensionDescriptor descriptor; + /** For use by generated code only. */ + public void internalInitSingular( + final ContainingType containingTypeDefaultInstance, + final Type defaultValue, + final MessageLite messageDefaultInstance, + final Internal.EnumLiteMap<?> enumTypeMap, + final int number, + final WireFormat.FieldType type) { + internalInit( + containingTypeDefaultInstance, defaultValue, messageDefaultInstance, + new ExtensionDescriptor(enumTypeMap, number, type, + false /* isRepeated */, false /* isPacked */)); + } + + /** For use by generated code only. */ + public void internalInitRepeated( + final ContainingType containingTypeDefaultInstance, + final MessageLite messageDefaultInstance, + final Internal.EnumLiteMap<?> enumTypeMap, + final int number, + final WireFormat.FieldType type, + final boolean isPacked) { + internalInit( + containingTypeDefaultInstance, (Type) Collections.emptyList(), + messageDefaultInstance, + new ExtensionDescriptor( + enumTypeMap, number, type, true /* isRepeated */, isPacked)); + } + + private ContainingType containingTypeDefaultInstance; + private Type defaultValue; + private MessageLite messageDefaultInstance; + private ExtensionDescriptor descriptor; /** * Default instance of the type being extended, used to identify that type. diff --git a/java/src/main/java/com/google/protobuf/Message.java b/java/src/main/java/com/google/protobuf/Message.java index c11abdc..8c29e21 100644 --- a/java/src/main/java/com/google/protobuf/Message.java +++ b/java/src/main/java/com/google/protobuf/Message.java @@ -296,9 +296,9 @@ public interface Message extends MessageLite { Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; - Builder mergeDelimitedFrom(InputStream input) + boolean mergeDelimitedFrom(InputStream input) throws IOException; - Builder mergeDelimitedFrom(InputStream input, + boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; } diff --git a/java/src/main/java/com/google/protobuf/MessageLite.java b/java/src/main/java/com/google/protobuf/MessageLite.java index 3ebe9bb..cf7f39e 100644 --- a/java/src/main/java/com/google/protobuf/MessageLite.java +++ b/java/src/main/java/com/google/protobuf/MessageLite.java @@ -317,14 +317,18 @@ public interface MessageLite { * then the message data. Use * {@link MessageLite#writeDelimitedTo(OutputStream)} to write messages in * this format. + * + * @returns True if successful, or false if the stream is at EOF when the + * method starts. Any other error (including reaching EOF during + * parsing) will cause an exception to be thrown. */ - Builder mergeDelimitedFrom(InputStream input) + boolean mergeDelimitedFrom(InputStream input) throws IOException; /** * Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions. */ - Builder mergeDelimitedFrom(InputStream input, + boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; } diff --git a/java/src/main/java/com/google/protobuf/RpcCallback.java b/java/src/main/java/com/google/protobuf/RpcCallback.java index 841c88a..1fd35ed 100644 --- a/java/src/main/java/com/google/protobuf/RpcCallback.java +++ b/java/src/main/java/com/google/protobuf/RpcCallback.java @@ -34,6 +34,12 @@ package com.google.protobuf; * Interface for an RPC callback, normally called when an RPC completes. * {@code ParameterType} is normally the method's response message type. * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * @author kenton@google.com Kenton Varda */ public interface RpcCallback<ParameterType> { diff --git a/java/src/main/java/com/google/protobuf/RpcChannel.java b/java/src/main/java/com/google/protobuf/RpcChannel.java index 204ff18..c6ec54f 100644 --- a/java/src/main/java/com/google/protobuf/RpcChannel.java +++ b/java/src/main/java/com/google/protobuf/RpcChannel.java @@ -44,6 +44,12 @@ package com.google.protobuf; * service.myMethod(controller, request, callback); * </pre> * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * @author kenton@google.com Kenton Varda */ public interface RpcChannel { diff --git a/java/src/main/java/com/google/protobuf/RpcController.java b/java/src/main/java/com/google/protobuf/RpcController.java index a017422..aaa5446 100644 --- a/java/src/main/java/com/google/protobuf/RpcController.java +++ b/java/src/main/java/com/google/protobuf/RpcController.java @@ -35,6 +35,12 @@ package com.google.protobuf; * purpose of the controller is to provide a way to manipulate settings * specific to the RPC implementation and to find out about RPC-level errors. * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * <p>The methods provided by the {@code RpcController} interface are intended * to be a "least common denominator" set of features which we expect all * implementations to support. Specific implementations may provide more diff --git a/java/src/main/java/com/google/protobuf/Service.java b/java/src/main/java/com/google/protobuf/Service.java index 33bcfd3..541585f 100644 --- a/java/src/main/java/com/google/protobuf/Service.java +++ b/java/src/main/java/com/google/protobuf/Service.java @@ -37,6 +37,12 @@ package com.google.protobuf; * interface can be used to call the methods of the service without knowing * its exact type at compile time (analogous to the Message interface). * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * @author kenton@google.com Kenton Varda */ public interface Service { diff --git a/java/src/main/java/com/google/protobuf/TextFormat.java b/java/src/main/java/com/google/protobuf/TextFormat.java index a855720..cb23f0c 100644 --- a/java/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/src/main/java/com/google/protobuf/TextFormat.java @@ -38,6 +38,7 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor; import java.io.IOException; import java.nio.CharBuffer; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -115,7 +116,7 @@ public final class TextFormat { } printUnknownFields(message.getUnknownFields(), generator); } - + public static void printField(final FieldDescriptor field, final Object value, final Appendable output) @@ -133,10 +134,10 @@ public final class TextFormat { } catch (IOException e) { throw new RuntimeException( "Writing to a StringBuilder threw an IOException (should never " + - "happen).", e); + "happen).", e); } } - + private static void printField(final FieldDescriptor field, final Object value, final TextGenerator generator) @@ -426,9 +427,9 @@ public final class TextFormat { Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE); private static final Pattern TOKEN = Pattern.compile( "[a-zA-Z_][0-9a-zA-Z_+-]*+|" + // an identifier - "[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number + "[.]?[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number "\"([^\"\n\\\\]|\\\\.)*+(\"|\\\\?$)|" + // a double-quoted string - "\'([^\"\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string + "\'([^\'\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string Pattern.MULTILINE); private static final Pattern DOUBLE_INFINITY = Pattern.compile( @@ -695,6 +696,21 @@ public final class TextFormat { * {@link ParseException}. */ public ByteString consumeByteString() throws ParseException { + List<ByteString> list = new ArrayList<ByteString>(); + consumeByteString(list); + while (currentToken.startsWith("'") || currentToken.startsWith("\"")) { + consumeByteString(list); + } + return ByteString.copyFrom(list); + } + + /** + * Like {@link #consumeByteString()} but adds each token of the string to + * the given list. String literals (whether bytes or text) may come in + * multiple adjacent tokens which are automatically concatenated, like in + * C or Python. + */ + private void consumeByteString(List<ByteString> list) throws ParseException { final char quote = currentToken.length() > 0 ? currentToken.charAt(0) : '\0'; if (quote != '\"' && quote != '\'') { @@ -711,7 +727,7 @@ public final class TextFormat { currentToken.substring(1, currentToken.length() - 1); final ByteString result = unescapeBytes(escaped); nextToken(); - return result; + list.add(result); } catch (InvalidEscapeSequenceException e) { throw parseException(e.getMessage()); } diff --git a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java index 7f7e493..26a15d0 100644 --- a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java +++ b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -551,19 +553,23 @@ public final class UnknownFieldSet implements MessageLite { return this; } - public Builder mergeDelimitedFrom(InputStream input) + public boolean mergeDelimitedFrom(InputStream input) throws IOException { - final int size = CodedInputStream.readRawVarint32(input); - final InputStream limitedInput = - new AbstractMessage.Builder.LimitedInputStream(input, size); - return mergeFrom(limitedInput, null); + final int firstByte = input.read(); + if (firstByte == -1) { + return false; + } + final int size = CodedInputStream.readRawVarint32(firstByte, input); + final InputStream limitedInput = new LimitedInputStream(input, size); + mergeFrom(limitedInput); + return true; } - public Builder mergeDelimitedFrom( + public boolean mergeDelimitedFrom( InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { // UnknownFieldSet has no extensions. - return mergeFrom(input); + return mergeDelimitedFrom(input); } public Builder mergeFrom( diff --git a/java/src/main/java/com/google/protobuf/WireFormat.java b/java/src/main/java/com/google/protobuf/WireFormat.java index 3b0bdcd..c46f7b0 100644 --- a/java/src/main/java/com/google/protobuf/WireFormat.java +++ b/java/src/main/java/com/google/protobuf/WireFormat.java @@ -113,10 +113,18 @@ public final class WireFormat { FIXED64 (JavaType.LONG , WIRETYPE_FIXED64 ), FIXED32 (JavaType.INT , WIRETYPE_FIXED32 ), BOOL (JavaType.BOOLEAN , WIRETYPE_VARINT ), - STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED), - GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ), - MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED), - BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED), + STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, + GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ) { + public boolean isPackable() { return false; } + }, + MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, + BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, UINT32 (JavaType.INT , WIRETYPE_VARINT ), ENUM (JavaType.ENUM , WIRETYPE_VARINT ), SFIXED32(JavaType.INT , WIRETYPE_FIXED32 ), @@ -134,6 +142,8 @@ public final class WireFormat { public JavaType getJavaType() { return javaType; } public int getWireType() { return wireType; } + + public boolean isPackable() { return true; } } // Field numbers for feilds in MessageSet wire format. diff --git a/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java b/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java deleted file mode 100644 index 6e87dc9..0000000 --- a/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java +++ /dev/null @@ -1,227 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.UnsupportedEncodingException; - -/** - * Immutable array of bytes. - * - * @author crazybob@google.com Bob Lee - * @author kenton@google.com Kenton Varda - */ -public final class ByteStringMicro { - private final byte[] bytes; - - private ByteStringMicro(final byte[] bytes) { - this.bytes = bytes; - } - - /** - * Gets the byte at the given index. - * - * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size - */ - public byte byteAt(final int index) { - return bytes[index]; - } - - /** - * Gets the number of bytes. - */ - public int size() { - return bytes.length; - } - - /** - * Returns {@code true} if the size is {@code 0}, {@code false} otherwise. - */ - public boolean isEmpty() { - return bytes.length == 0; - } - - // ================================================================= - // byte[] -> ByteStringMicro - - /** - * Empty ByteStringMicro. - */ - public static final ByteStringMicro EMPTY = new ByteStringMicro(new byte[0]); - - /** - * Copies the given bytes into a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFrom(final byte[] bytes, final int offset, - final int size) { - final byte[] copy = new byte[size]; - System.arraycopy(bytes, offset, copy, 0, size); - return new ByteStringMicro(copy); - } - - /** - * Copies the given bytes into a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFrom(final byte[] bytes) { - return copyFrom(bytes, 0, bytes.length); - } - - /** - * Encodes {@code text} into a sequence of bytes using the named charset - * and returns the result as a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFrom(final String text, final String charsetName) - throws UnsupportedEncodingException { - return new ByteStringMicro(text.getBytes(charsetName)); - } - - /** - * Encodes {@code text} into a sequence of UTF-8 bytes and returns the - * result as a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFromUtf8(final String text) { - try { - return new ByteStringMicro(text.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported?"); - } - } - - // ================================================================= - // ByteStringMicro -> byte[] - - /** - * Copies bytes into a buffer at the given offset. - * - * @param target buffer to copy into - * @param offset in the target buffer - */ - public void copyTo(final byte[] target, final int offset) { - System.arraycopy(bytes, 0, target, offset, bytes.length); - } - - /** - * Copies bytes into a buffer. - * - * @param target buffer to copy into - * @param sourceOffset offset within these bytes - * @param targetOffset offset within the target buffer - * @param size number of bytes to copy - */ - public void copyTo(final byte[] target, final int sourceOffset, - final int targetOffset, - final int size) { - System.arraycopy(bytes, sourceOffset, target, targetOffset, size); - } - - /** - * Copies bytes to a {@code byte[]}. - */ - public byte[] toByteArray() { - final int size = bytes.length; - final byte[] copy = new byte[size]; - System.arraycopy(bytes, 0, copy, 0, size); - return copy; - } - - /** - * Constructs a new {@code String} by decoding the bytes using the - * specified charset. - */ - public String toString(final String charsetName) - throws UnsupportedEncodingException { - return new String(bytes, charsetName); - } - - /** - * Constructs a new {@code String} by decoding the bytes as UTF-8. - */ - public String toStringUtf8() { - try { - return new String(bytes, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported?"); - } - } - - // ================================================================= - // equals() and hashCode() - - //@Override for compatibility with Java 1.3 code we can't use annotations - public boolean equals(final Object o) { - if (o == this) { - return true; - } - - if (!(o instanceof ByteStringMicro)) { - return false; - } - - final ByteStringMicro other = (ByteStringMicro) o; - final int size = bytes.length; - if (size != other.bytes.length) { - return false; - } - - final byte[] thisBytes = bytes; - final byte[] otherBytes = other.bytes; - for (int i = 0; i < size; i++) { - if (thisBytes[i] != otherBytes[i]) { - return false; - } - } - - return true; - } - - private volatile int hash = 0; - - //@Override for compatibility with Java 1.3 code we can't use annotations - public int hashCode() { - int h = hash; - - if (h == 0) { - final byte[] thisBytes = bytes; - final int size = bytes.length; - - h = size; - for (int i = 0; i < size; i++) { - h = h * 31 + thisBytes[i]; - } - if (h == 0) { - h = 1; - } - - hash = h; - } - - return h; - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java b/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java deleted file mode 100644 index 0791b8f..0000000 --- a/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java +++ /dev/null @@ -1,804 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Reads and decodes protocol message fields. - * - * This class contains two kinds of methods: methods that read specific - * protocol message constructs and field types (e.g. {@link #readTag()} and - * {@link #readInt32()}) and methods that read low-level values (e.g. - * {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading - * encoded protocol messages, you should use the former methods, but if you are - * reading some other format of your own design, use the latter. - * - * @author kenton@google.com Kenton Varda - */ -public final class CodedInputStreamMicro { - /** - * Create a new CodedInputStream wrapping the given InputStream. - */ - public static CodedInputStreamMicro newInstance(final InputStream input) { - return new CodedInputStreamMicro(input); - } - - /** - * Create a new CodedInputStream wrapping the given byte array. - */ - public static CodedInputStreamMicro newInstance(final byte[] buf) { - return newInstance(buf, 0, buf.length); - } - - /** - * Create a new CodedInputStream wrapping the given byte array slice. - */ - public static CodedInputStreamMicro newInstance(final byte[] buf, final int off, - final int len) { - return new CodedInputStreamMicro(buf, off, len); - } - - // ----------------------------------------------------------------- - - /** - * Attempt to read a field tag, returning zero if we have reached EOF. - * Protocol message parsers use this to read tags, since a protocol message - * may legally end wherever a tag occurs, and zero is not a valid tag number. - */ - public int readTag() throws IOException { - if (isAtEnd()) { - lastTag = 0; - return 0; - } - - lastTag = readRawVarint32(); - if (lastTag == 0) { - // If we actually read zero, that's not a valid tag. - throw InvalidProtocolBufferMicroException.invalidTag(); - } - return lastTag; - } - - /** - * Verifies that the last call to readTag() returned the given tag value. - * This is used to verify that a nested group ended with the correct - * end tag. - * - * @throws InvalidProtocolBufferMicroException {@code value} does not match the - * last tag. - */ - public void checkLastTagWas(final int value) - throws InvalidProtocolBufferMicroException { - if (lastTag != value) { - throw InvalidProtocolBufferMicroException.invalidEndTag(); - } - } - - /** - * Reads and discards a single field, given its tag value. - * - * @return {@code false} if the tag is an endgroup tag, in which case - * nothing is skipped. Otherwise, returns {@code true}. - */ - public boolean skipField(final int tag) throws IOException { - switch (WireFormatMicro.getTagWireType(tag)) { - case WireFormatMicro.WIRETYPE_VARINT: - readInt32(); - return true; - case WireFormatMicro.WIRETYPE_FIXED64: - readRawLittleEndian64(); - return true; - case WireFormatMicro.WIRETYPE_LENGTH_DELIMITED: - skipRawBytes(readRawVarint32()); - return true; - case WireFormatMicro.WIRETYPE_START_GROUP: - skipMessage(); - checkLastTagWas( - WireFormatMicro.makeTag(WireFormatMicro.getTagFieldNumber(tag), - WireFormatMicro.WIRETYPE_END_GROUP)); - return true; - case WireFormatMicro.WIRETYPE_END_GROUP: - return false; - case WireFormatMicro.WIRETYPE_FIXED32: - readRawLittleEndian32(); - return true; - default: - throw InvalidProtocolBufferMicroException.invalidWireType(); - } - } - - /** - * Reads and discards an entire message. This will read either until EOF - * or until an endgroup tag, whichever comes first. - */ - public void skipMessage() throws IOException { - while (true) { - final int tag = readTag(); - if (tag == 0 || !skipField(tag)) { - return; - } - } - } - - // ----------------------------------------------------------------- - - /** Read a {@code double} field value from the stream. */ - public double readDouble() throws IOException { - return Double.longBitsToDouble(readRawLittleEndian64()); - } - - /** Read a {@code float} field value from the stream. */ - public float readFloat() throws IOException { - return Float.intBitsToFloat(readRawLittleEndian32()); - } - - /** Read a {@code uint64} field value from the stream. */ - public long readUInt64() throws IOException { - return readRawVarint64(); - } - - /** Read an {@code int64} field value from the stream. */ - public long readInt64() throws IOException { - return readRawVarint64(); - } - - /** Read an {@code int32} field value from the stream. */ - public int readInt32() throws IOException { - return readRawVarint32(); - } - - /** Read a {@code fixed64} field value from the stream. */ - public long readFixed64() throws IOException { - return readRawLittleEndian64(); - } - - /** Read a {@code fixed32} field value from the stream. */ - public int readFixed32() throws IOException { - return readRawLittleEndian32(); - } - - /** Read a {@code bool} field value from the stream. */ - public boolean readBool() throws IOException { - return readRawVarint32() != 0; - } - - /** Read a {@code string} field value from the stream. */ - public String readString() throws IOException { - final int size = readRawVarint32(); - if (size <= (bufferSize - bufferPos) && size > 0) { - // Fast path: We already have the bytes in a contiguous buffer, so - // just copy directly from it. - final String result = new String(buffer, bufferPos, size, "UTF-8"); - bufferPos += size; - return result; - } else { - // Slow path: Build a byte array first then copy it. - return new String(readRawBytes(size), "UTF-8"); - } - } - - /** Read a {@code group} field value from the stream. */ - public void readGroup(final MessageMicro msg, final int fieldNumber) - throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferMicroException.recursionLimitExceeded(); - } - ++recursionDepth; - msg.mergeFrom(this); - checkLastTagWas( - WireFormatMicro.makeTag(fieldNumber, WireFormatMicro.WIRETYPE_END_GROUP)); - --recursionDepth; - } - - public void readMessage(final MessageMicro msg) - throws IOException { - final int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferMicroException.recursionLimitExceeded(); - } - final int oldLimit = pushLimit(length); - ++recursionDepth; - msg.mergeFrom(this); - checkLastTagWas(0); - --recursionDepth; - popLimit(oldLimit); - } - - /** Read a {@code bytes} field value from the stream. */ - public ByteStringMicro readBytes() throws IOException { - final int size = readRawVarint32(); - if (size <= (bufferSize - bufferPos) && size > 0) { - // Fast path: We already have the bytes in a contiguous buffer, so - // just copy directly from it. - final ByteStringMicro result = ByteStringMicro.copyFrom(buffer, bufferPos, size); - bufferPos += size; - return result; - } else { - // Slow path: Build a byte array first then copy it. - return ByteStringMicro.copyFrom(readRawBytes(size)); - } - } - - /** Read a {@code uint32} field value from the stream. */ - public int readUInt32() throws IOException { - return readRawVarint32(); - } - - /** - * Read an enum field value from the stream. Caller is responsible - * for converting the numeric value to an actual enum. - */ - public int readEnum() throws IOException { - return readRawVarint32(); - } - - /** Read an {@code sfixed32} field value from the stream. */ - public int readSFixed32() throws IOException { - return readRawLittleEndian32(); - } - - /** Read an {@code sfixed64} field value from the stream. */ - public long readSFixed64() throws IOException { - return readRawLittleEndian64(); - } - - /** Read an {@code sint32} field value from the stream. */ - public int readSInt32() throws IOException { - return decodeZigZag32(readRawVarint32()); - } - - /** Read an {@code sint64} field value from the stream. */ - public long readSInt64() throws IOException { - return decodeZigZag64(readRawVarint64()); - } - - // ================================================================= - - /** - * Read a raw Varint from the stream. If larger than 32 bits, discard the - * upper bits. - */ - public int readRawVarint32() throws IOException { - byte tmp = readRawByte(); - if (tmp >= 0) { - return tmp; - } - int result = tmp & 0x7f; - if ((tmp = readRawByte()) >= 0) { - result |= tmp << 7; - } else { - result |= (tmp & 0x7f) << 7; - if ((tmp = readRawByte()) >= 0) { - result |= tmp << 14; - } else { - result |= (tmp & 0x7f) << 14; - if ((tmp = readRawByte()) >= 0) { - result |= tmp << 21; - } else { - result |= (tmp & 0x7f) << 21; - result |= (tmp = readRawByte()) << 28; - if (tmp < 0) { - // Discard upper 32 bits. - for (int i = 0; i < 5; i++) { - if (readRawByte() >= 0) { - return result; - } - } - throw InvalidProtocolBufferMicroException.malformedVarint(); - } - } - } - } - return result; - } - - /** - * Reads a varint from the input one byte at a time, so that it does not - * read any bytes after the end of the varint. If you simply wrapped the - * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)} - * then you would probably end up reading past the end of the varint since - * CodedInputStream buffers its input. - */ - static int readRawVarint32(final InputStream input) throws IOException { - int result = 0; - int offset = 0; - for (; offset < 32; offset += 7) { - final int b = input.read(); - if (b == -1) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - result |= (b & 0x7f) << offset; - if ((b & 0x80) == 0) { - return result; - } - } - // Keep reading up to 64 bits. - for (; offset < 64; offset += 7) { - final int b = input.read(); - if (b == -1) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - if ((b & 0x80) == 0) { - return result; - } - } - throw InvalidProtocolBufferMicroException.malformedVarint(); - } - - /** Read a raw Varint from the stream. */ - public long readRawVarint64() throws IOException { - int shift = 0; - long result = 0; - while (shift < 64) { - final byte b = readRawByte(); - result |= (long)(b & 0x7F) << shift; - if ((b & 0x80) == 0) { - return result; - } - shift += 7; - } - throw InvalidProtocolBufferMicroException.malformedVarint(); - } - - /** Read a 32-bit little-endian integer from the stream. */ - public int readRawLittleEndian32() throws IOException { - final byte b1 = readRawByte(); - final byte b2 = readRawByte(); - final byte b3 = readRawByte(); - final byte b4 = readRawByte(); - return ((b1 & 0xff) ) | - ((b2 & 0xff) << 8) | - ((b3 & 0xff) << 16) | - ((b4 & 0xff) << 24); - } - - /** Read a 64-bit little-endian integer from the stream. */ - public long readRawLittleEndian64() throws IOException { - final byte b1 = readRawByte(); - final byte b2 = readRawByte(); - final byte b3 = readRawByte(); - final byte b4 = readRawByte(); - final byte b5 = readRawByte(); - final byte b6 = readRawByte(); - final byte b7 = readRawByte(); - final byte b8 = readRawByte(); - return (((long)b1 & 0xff) ) | - (((long)b2 & 0xff) << 8) | - (((long)b3 & 0xff) << 16) | - (((long)b4 & 0xff) << 24) | - (((long)b5 & 0xff) << 32) | - (((long)b6 & 0xff) << 40) | - (((long)b7 & 0xff) << 48) | - (((long)b8 & 0xff) << 56); - } - - /** - * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n An unsigned 32-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - * @return A signed 32-bit integer. - */ - public static int decodeZigZag32(final int n) { - return (n >>> 1) ^ -(n & 1); - } - - /** - * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n An unsigned 64-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - * @return A signed 64-bit integer. - */ - public static long decodeZigZag64(final long n) { - return (n >>> 1) ^ -(n & 1); - } - - // ----------------------------------------------------------------- - - private final byte[] buffer; - private int bufferSize; - private int bufferSizeAfterLimit; - private int bufferPos; - private final InputStream input; - private int lastTag; - - /** - * The total number of bytes read before the current buffer. The total - * bytes read up to the current position can be computed as - * {@code totalBytesRetired + bufferPos}. - */ - private int totalBytesRetired; - - /** The absolute position of the end of the current message. */ - private int currentLimit = Integer.MAX_VALUE; - - /** See setRecursionLimit() */ - private int recursionDepth; - private int recursionLimit = DEFAULT_RECURSION_LIMIT; - - /** See setSizeLimit() */ - private int sizeLimit = DEFAULT_SIZE_LIMIT; - - private static final int DEFAULT_RECURSION_LIMIT = 64; - private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB - private static final int BUFFER_SIZE = 4096; - - private CodedInputStreamMicro(final byte[] buffer, final int off, final int len) { - this.buffer = buffer; - bufferSize = off + len; - bufferPos = off; - input = null; - } - - private CodedInputStreamMicro(final InputStream input) { - buffer = new byte[BUFFER_SIZE]; - bufferSize = 0; - bufferPos = 0; - this.input = input; - } - - /** - * Set the maximum message recursion depth. In order to prevent malicious - * messages from causing stack overflows, {@code CodedInputStream} limits - * how deeply messages may be nested. The default limit is 64. - * - * @return the old limit. - */ - public int setRecursionLimit(final int limit) { - if (limit < 0) { - throw new IllegalArgumentException( - "Recursion limit cannot be negative: " + limit); - } - final int oldLimit = recursionLimit; - recursionLimit = limit; - return oldLimit; - } - - /** - * Set the maximum message size. In order to prevent malicious - * messages from exhausting memory or causing integer overflows, - * {@code CodedInputStream} limits how large a message may be. - * The default limit is 64MB. You should set this limit as small - * as you can without harming your app's functionality. Note that - * size limits only apply when reading from an {@code InputStream}, not - * when constructed around a raw byte array (nor with - * {@link ByteStringMicro#newCodedInput}). - * <p> - * If you want to read several messages from a single CodedInputStream, you - * could call {@link #resetSizeCounter()} after each one to avoid hitting the - * size limit. - * - * @return the old limit. - */ - public int setSizeLimit(final int limit) { - if (limit < 0) { - throw new IllegalArgumentException( - "Size limit cannot be negative: " + limit); - } - final int oldLimit = sizeLimit; - sizeLimit = limit; - return oldLimit; - } - - /** - * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). - */ - public void resetSizeCounter() { - totalBytesRetired = 0; - } - - /** - * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This - * is called when descending into a length-delimited embedded message. - * - * @return the old limit. - */ - public int pushLimit(int byteLimit) throws InvalidProtocolBufferMicroException { - if (byteLimit < 0) { - throw InvalidProtocolBufferMicroException.negativeSize(); - } - byteLimit += totalBytesRetired + bufferPos; - final int oldLimit = currentLimit; - if (byteLimit > oldLimit) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - currentLimit = byteLimit; - - recomputeBufferSizeAfterLimit(); - - return oldLimit; - } - - private void recomputeBufferSizeAfterLimit() { - bufferSize += bufferSizeAfterLimit; - final int bufferEnd = totalBytesRetired + bufferSize; - if (bufferEnd > currentLimit) { - // Limit is in current buffer. - bufferSizeAfterLimit = bufferEnd - currentLimit; - bufferSize -= bufferSizeAfterLimit; - } else { - bufferSizeAfterLimit = 0; - } - } - - /** - * Discards the current limit, returning to the previous limit. - * - * @param oldLimit The old limit, as returned by {@code pushLimit}. - */ - public void popLimit(final int oldLimit) { - currentLimit = oldLimit; - recomputeBufferSizeAfterLimit(); - } - - /** - * Returns the number of bytes to be read before the current limit. - * If no limit is set, returns -1. - */ - public int getBytesUntilLimit() { - if (currentLimit == Integer.MAX_VALUE) { - return -1; - } - - final int currentAbsolutePosition = totalBytesRetired + bufferPos; - return currentLimit - currentAbsolutePosition; - } - - /** - * Returns true if the stream has reached the end of the input. This is the - * case if either the end of the underlying input source has been reached or - * if the stream has reached a limit created using {@link #pushLimit(int)}. - */ - public boolean isAtEnd() throws IOException { - return bufferPos == bufferSize && !refillBuffer(false); - } - - /** - * Called with {@code this.buffer} is empty to read more bytes from the - * input. If {@code mustSucceed} is true, refillBuffer() gurantees that - * either there will be at least one byte in the buffer when it returns - * or it will throw an exception. If {@code mustSucceed} is false, - * refillBuffer() returns false if no more bytes were available. - */ - private boolean refillBuffer(final boolean mustSucceed) throws IOException { - if (bufferPos < bufferSize) { - throw new IllegalStateException( - "refillBuffer() called when buffer wasn't empty."); - } - - if (totalBytesRetired + bufferSize == currentLimit) { - // Oops, we hit a limit. - if (mustSucceed) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } else { - return false; - } - } - - totalBytesRetired += bufferSize; - - bufferPos = 0; - bufferSize = (input == null) ? -1 : input.read(buffer); - if (bufferSize == 0 || bufferSize < -1) { - throw new IllegalStateException( - "InputStream#read(byte[]) returned invalid result: " + bufferSize + - "\nThe InputStream implementation is buggy."); - } - if (bufferSize == -1) { - bufferSize = 0; - if (mustSucceed) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } else { - return false; - } - } else { - recomputeBufferSizeAfterLimit(); - final int totalBytesRead = - totalBytesRetired + bufferSize + bufferSizeAfterLimit; - if (totalBytesRead > sizeLimit || totalBytesRead < 0) { - throw InvalidProtocolBufferMicroException.sizeLimitExceeded(); - } - return true; - } - } - - /** - * Read one byte from the input. - * - * @throws InvalidProtocolBufferMicroException The end of the stream or the current - * limit was reached. - */ - public byte readRawByte() throws IOException { - if (bufferPos == bufferSize) { - refillBuffer(true); - } - return buffer[bufferPos++]; - } - - /** - * Read a fixed size of bytes from the input. - * - * @throws InvalidProtocolBufferMicroException The end of the stream or the current - * limit was reached. - */ - public byte[] readRawBytes(final int size) throws IOException { - if (size < 0) { - throw InvalidProtocolBufferMicroException.negativeSize(); - } - - if (totalBytesRetired + bufferPos + size > currentLimit) { - // Read to the end of the stream anyway. - skipRawBytes(currentLimit - totalBytesRetired - bufferPos); - // Then fail. - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - - if (size <= bufferSize - bufferPos) { - // We have all the bytes we need already. - final byte[] bytes = new byte[size]; - System.arraycopy(buffer, bufferPos, bytes, 0, size); - bufferPos += size; - return bytes; - } else if (size < BUFFER_SIZE) { - // Reading more bytes than are in the buffer, but not an excessive number - // of bytes. We can safely allocate the resulting array ahead of time. - - // First copy what we have. - final byte[] bytes = new byte[size]; - int pos = bufferSize - bufferPos; - System.arraycopy(buffer, bufferPos, bytes, 0, pos); - bufferPos = bufferSize; - - // We want to use refillBuffer() and then copy from the buffer into our - // byte array rather than reading directly into our byte array because - // the input may be unbuffered. - refillBuffer(true); - - while (size - pos > bufferSize) { - System.arraycopy(buffer, 0, bytes, pos, bufferSize); - pos += bufferSize; - bufferPos = bufferSize; - refillBuffer(true); - } - - System.arraycopy(buffer, 0, bytes, pos, size - pos); - bufferPos = size - pos; - - return bytes; - } else { - // The size is very large. For security reasons, we can't allocate the - // entire byte array yet. The size comes directly from the input, so a - // maliciously-crafted message could provide a bogus very large size in - // order to trick the app into allocating a lot of memory. We avoid this - // by allocating and reading only a small chunk at a time, so that the - // malicious message must actually *be* extremely large to cause - // problems. Meanwhile, we limit the allowed size of a message elsewhere. - - // Remember the buffer markers since we'll have to copy the bytes out of - // it later. - final int originalBufferPos = bufferPos; - final int originalBufferSize = bufferSize; - - // Mark the current buffer consumed. - totalBytesRetired += bufferSize; - bufferPos = 0; - bufferSize = 0; - - // Read all the rest of the bytes we need. - int sizeLeft = size - (originalBufferSize - originalBufferPos); - - // For compatibility with Java 1.3 use Vector - final java.util.Vector chunks = new java.util.Vector(); - - while (sizeLeft > 0) { - final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)]; - int pos = 0; - while (pos < chunk.length) { - final int n = (input == null) ? -1 : - input.read(chunk, pos, chunk.length - pos); - if (n == -1) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - totalBytesRetired += n; - pos += n; - } - sizeLeft -= chunk.length; - chunks.addElement(chunk); - } - - // OK, got everything. Now concatenate it all into one buffer. - final byte[] bytes = new byte[size]; - - // Start by copying the leftover bytes from this.buffer. - int pos = originalBufferSize - originalBufferPos; - System.arraycopy(buffer, originalBufferPos, bytes, 0, pos); - - // And now all the chunks. - for (int i = 0; i < chunks.size(); i++) { - byte [] chunk = (byte [])chunks.elementAt(i); - System.arraycopy(chunk, 0, bytes, pos, chunk.length); - pos += chunk.length; - } - - // Done. - return bytes; - } - } - - /** - * Reads and discards {@code size} bytes. - * - * @throws InvalidProtocolBufferMicroException The end of the stream or the current - * limit was reached. - */ - public void skipRawBytes(final int size) throws IOException { - if (size < 0) { - throw InvalidProtocolBufferMicroException.negativeSize(); - } - - if (totalBytesRetired + bufferPos + size > currentLimit) { - // Read to the end of the stream anyway. - skipRawBytes(currentLimit - totalBytesRetired - bufferPos); - // Then fail. - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - - if (size <= bufferSize - bufferPos) { - // We have all the bytes we need already. - bufferPos += size; - } else { - // Skipping more bytes than are in the buffer. First skip what we have. - int pos = bufferSize - bufferPos; - totalBytesRetired += pos; - bufferPos = 0; - bufferSize = 0; - - // Then skip directly from the InputStream for the rest. - while (pos < size) { - final int n = (input == null) ? -1 : (int) input.skip(size - pos); - if (n <= 0) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - pos += n; - totalBytesRetired += n; - } - } - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java b/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java deleted file mode 100644 index 68b6e97..0000000 --- a/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java +++ /dev/null @@ -1,996 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.OutputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -/** - * Encodes and writes protocol message fields. - * - * <p>This class contains two kinds of methods: methods that write specific - * protocol message constructs and field types (e.g. {@link #writeTag} and - * {@link #writeInt32}) and methods that write low-level values (e.g. - * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are - * writing encoded protocol messages, you should use the former methods, but if - * you are writing some other format of your own design, use the latter. - * - * <p>This class is totally unsynchronized. - * - * @author kneton@google.com Kenton Varda - */ -public final class CodedOutputStreamMicro { - private final byte[] buffer; - private final int limit; - private int position; - - private final OutputStream output; - - /** - * The buffer size used in {@link #newInstance(OutputStream)}. - */ - public static final int DEFAULT_BUFFER_SIZE = 4096; - - private CodedOutputStreamMicro(final byte[] buffer, final int offset, - final int length) { - output = null; - this.buffer = buffer; - position = offset; - limit = offset + length; - } - - private CodedOutputStreamMicro(final OutputStream output, final byte[] buffer) { - this.output = output; - this.buffer = buffer; - position = 0; - limit = buffer.length; - } - - /** - * Create a new {@code CodedOutputStream} wrapping the given - * {@code OutputStream}. - */ - public static CodedOutputStreamMicro newInstance(final OutputStream output) { - return newInstance(output, DEFAULT_BUFFER_SIZE); - } - - /** - * Create a new {@code CodedOutputStream} wrapping the given - * {@code OutputStream} with a given buffer size. - */ - public static CodedOutputStreamMicro newInstance(final OutputStream output, - final int bufferSize) { - return new CodedOutputStreamMicro(output, new byte[bufferSize]); - } - - /** - * Create a new {@code CodedOutputStream} that writes directly to the given - * byte array. If more bytes are written than fit in the array, - * {@link OutOfSpaceException} will be thrown. Writing directly to a flat - * array is faster than writing to an {@code OutputStream}. - */ - public static CodedOutputStreamMicro newInstance(final byte[] flatArray) { - return newInstance(flatArray, 0, flatArray.length); - } - - /** - * Create a new {@code CodedOutputStream} that writes directly to the given - * byte array slice. If more bytes are written than fit in the slice, - * {@link OutOfSpaceException} will be thrown. Writing directly to a flat - * array is faster than writing to an {@code OutputStream}. - */ - public static CodedOutputStreamMicro newInstance(final byte[] flatArray, - final int offset, - final int length) { - return new CodedOutputStreamMicro(flatArray, offset, length); - } - - // ----------------------------------------------------------------- - - /** Write a {@code double} field, including tag, to the stream. */ - public void writeDouble(final int fieldNumber, final double value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); - writeDoubleNoTag(value); - } - - /** Write a {@code float} field, including tag, to the stream. */ - public void writeFloat(final int fieldNumber, final float value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); - writeFloatNoTag(value); - } - - /** Write a {@code uint64} field, including tag, to the stream. */ - public void writeUInt64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeUInt64NoTag(value); - } - - /** Write an {@code int64} field, including tag, to the stream. */ - public void writeInt64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeInt64NoTag(value); - } - - /** Write an {@code int32} field, including tag, to the stream. */ - public void writeInt32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeInt32NoTag(value); - } - - /** Write a {@code fixed64} field, including tag, to the stream. */ - public void writeFixed64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); - writeFixed64NoTag(value); - } - - /** Write a {@code fixed32} field, including tag, to the stream. */ - public void writeFixed32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); - writeFixed32NoTag(value); - } - - /** Write a {@code bool} field, including tag, to the stream. */ - public void writeBool(final int fieldNumber, final boolean value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeBoolNoTag(value); - } - - /** Write a {@code string} field, including tag, to the stream. */ - public void writeString(final int fieldNumber, final String value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeStringNoTag(value); - } - - /** Write a {@code StringUtf8Micro} field, including tag, to the stream. */ - public void writeStringUtf8(final int fieldNumber, final StringUtf8Micro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeStringUtf8NoTag(value); - } - - /** Write a {@code group} field, including tag, to the stream. */ - public void writeGroup(final int fieldNumber, final MessageMicro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_START_GROUP); - writeGroupNoTag(value); - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_END_GROUP); - } - - /** Write an embedded message field, including tag, to the stream. */ - public void writeMessage(final int fieldNumber, final MessageMicro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeMessageNoTag(value); - } - - /** Write a {@code bytes} field, including tag, to the stream. */ - public void writeBytes(final int fieldNumber, final ByteStringMicro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeBytesNoTag(value); - } - - /** Write a {@code uint32} field, including tag, to the stream. */ - public void writeUInt32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeUInt32NoTag(value); - } - - /** - * Write an enum field, including tag, to the stream. Caller is responsible - * for converting the enum value to its numeric value. - */ - public void writeEnum(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeEnumNoTag(value); - } - - /** Write an {@code sfixed32} field, including tag, to the stream. */ - public void writeSFixed32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); - writeSFixed32NoTag(value); - } - - /** Write an {@code sfixed64} field, including tag, to the stream. */ - public void writeSFixed64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); - writeSFixed64NoTag(value); - } - - /** Write an {@code sint32} field, including tag, to the stream. */ - public void writeSInt32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeSInt32NoTag(value); - } - - /** Write an {@code sint64} field, including tag, to the stream. */ - public void writeSInt64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeSInt64NoTag(value); - } - - /** - * Write a MessageSet extension field to the stream. For historical reasons, - * the wire format differs from normal fields. - */ -// public void writeMessageSetExtension(final int fieldNumber, -// final MessageMicro value) -// throws IOException { -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); -// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); -// writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value); -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); -// } - - /** - * Write an unparsed MessageSet extension field to the stream. For - * historical reasons, the wire format differs from normal fields. - */ -// public void writeRawMessageSetExtension(final int fieldNumber, -// final ByteStringMicro value) -// throws IOException { -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); -// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); -// writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value); -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); -// } - - // ----------------------------------------------------------------- - - /** Write a {@code double} field to the stream. */ - public void writeDoubleNoTag(final double value) throws IOException { - writeRawLittleEndian64(Double.doubleToLongBits(value)); - } - - /** Write a {@code float} field to the stream. */ - public void writeFloatNoTag(final float value) throws IOException { - writeRawLittleEndian32(Float.floatToIntBits(value)); - } - - /** Write a {@code uint64} field to the stream. */ - public void writeUInt64NoTag(final long value) throws IOException { - writeRawVarint64(value); - } - - /** Write an {@code int64} field to the stream. */ - public void writeInt64NoTag(final long value) throws IOException { - writeRawVarint64(value); - } - - /** Write an {@code int32} field to the stream. */ - public void writeInt32NoTag(final int value) throws IOException { - if (value >= 0) { - writeRawVarint32(value); - } else { - // Must sign-extend. - writeRawVarint64(value); - } - } - - /** Write a {@code fixed64} field to the stream. */ - public void writeFixed64NoTag(final long value) throws IOException { - writeRawLittleEndian64(value); - } - - /** Write a {@code fixed32} field to the stream. */ - public void writeFixed32NoTag(final int value) throws IOException { - writeRawLittleEndian32(value); - } - - /** Write a {@code bool} field to the stream. */ - public void writeBoolNoTag(final boolean value) throws IOException { - writeRawByte(value ? 1 : 0); - } - - /** Write a {@code string} field to the stream. */ - public void writeStringNoTag(final String value) throws IOException { - // Unfortunately there does not appear to be any way to tell Java to encode - // UTF-8 directly into our buffer, so we have to let it create its own byte - // array and then copy. - final byte[] bytes = value.getBytes("UTF-8"); - writeRawVarint32(bytes.length); - writeRawBytes(bytes); - } - - /** Write a {@code StringUtf8Micro} field to the stream. */ - public void writeStringUtf8NoTag(final StringUtf8Micro value) throws IOException { - final byte[] bytes = value.getBytes(); - writeRawVarint32(bytes.length); - writeRawBytes(bytes); - } - - /** Write a {@code group} field to the stream. */ - public void writeGroupNoTag(final MessageMicro value) throws IOException { - value.writeTo(this); - } - - /** Write an embedded message field to the stream. */ - public void writeMessageNoTag(final MessageMicro value) throws IOException { - writeRawVarint32(value.getCachedSize()); - value.writeTo(this); - } - - /** Write a {@code bytes} field to the stream. */ - public void writeBytesNoTag(final ByteStringMicro value) throws IOException { - final byte[] bytes = value.toByteArray(); - writeRawVarint32(bytes.length); - writeRawBytes(bytes); - } - - /** Write a {@code uint32} field to the stream. */ - public void writeUInt32NoTag(final int value) throws IOException { - writeRawVarint32(value); - } - - /** - * Write an enum field to the stream. Caller is responsible - * for converting the enum value to its numeric value. - */ - public void writeEnumNoTag(final int value) throws IOException { - writeRawVarint32(value); - } - - /** Write an {@code sfixed32} field to the stream. */ - public void writeSFixed32NoTag(final int value) throws IOException { - writeRawLittleEndian32(value); - } - - /** Write an {@code sfixed64} field to the stream. */ - public void writeSFixed64NoTag(final long value) throws IOException { - writeRawLittleEndian64(value); - } - - /** Write an {@code sint32} field to the stream. */ - public void writeSInt32NoTag(final int value) throws IOException { - writeRawVarint32(encodeZigZag32(value)); - } - - /** Write an {@code sint64} field to the stream. */ - public void writeSInt64NoTag(final long value) throws IOException { - writeRawVarint64(encodeZigZag64(value)); - } - - // ================================================================= - - /** - * Compute the number of bytes that would be needed to encode a - * {@code double} field, including tag. - */ - public static int computeDoubleSize(final int fieldNumber, - final double value) { - return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code float} field, including tag. - */ - public static int computeFloatSize(final int fieldNumber, final float value) { - return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code uint64} field, including tag. - */ - public static int computeUInt64Size(final int fieldNumber, final long value) { - return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code int64} field, including tag. - */ - public static int computeInt64Size(final int fieldNumber, final long value) { - return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code int32} field, including tag. - */ - public static int computeInt32Size(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code fixed64} field, including tag. - */ - public static int computeFixed64Size(final int fieldNumber, - final long value) { - return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code fixed32} field, including tag. - */ - public static int computeFixed32Size(final int fieldNumber, - final int value) { - return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code bool} field, including tag. - */ - public static int computeBoolSize(final int fieldNumber, - final boolean value) { - return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code string} field, including tag. - */ - public static int computeStringSize(final int fieldNumber, - final String value) { - return computeTagSize(fieldNumber) + computeStringSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code StringUtf8Micro} field, including tag. - */ - public static int computeStringUtf8Size(final int fieldNumber, - final StringUtf8Micro value) { - return computeTagSize(fieldNumber) + computeStringUtf8SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code group} field, including tag. - */ - public static int computeGroupSize(final int fieldNumber, - final MessageMicro value) { - return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * embedded message field, including tag. - */ - public static int computeMessageSize(final int fieldNumber, - final MessageMicro value) { - return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code bytes} field, including tag. - */ - public static int computeBytesSize(final int fieldNumber, - final ByteStringMicro value) { - return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code uint32} field, including tag. - */ - public static int computeUInt32Size(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * enum field, including tag. Caller is responsible for converting the - * enum value to its numeric value. - */ - public static int computeEnumSize(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sfixed32} field, including tag. - */ - public static int computeSFixed32Size(final int fieldNumber, - final int value) { - return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sfixed64} field, including tag. - */ - public static int computeSFixed64Size(final int fieldNumber, - final long value) { - return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sint32} field, including tag. - */ - public static int computeSInt32Size(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sint64} field, including tag. - */ - public static int computeSInt64Size(final int fieldNumber, final long value) { - return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * MessageSet extension to the stream. For historical reasons, - * the wire format differs from normal fields. - */ -// public static int computeMessageSetExtensionSize( -// final int fieldNumber, final MessageMicro value) { -// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + -// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + -// computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value); -// } - - /** - * Compute the number of bytes that would be needed to encode an - * unparsed MessageSet extension field to the stream. For - * historical reasons, the wire format differs from normal fields. - */ -// public static int computeRawMessageSetExtensionSize( -// final int fieldNumber, final ByteStringMicro value) { -// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + -// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + -// computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value); -// } - - // ----------------------------------------------------------------- - - /** - * Compute the number of bytes that would be needed to encode a - * {@code double} field, including tag. - */ - public static int computeDoubleSizeNoTag(final double value) { - return LITTLE_ENDIAN_64_SIZE; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code float} field, including tag. - */ - public static int computeFloatSizeNoTag(final float value) { - return LITTLE_ENDIAN_32_SIZE; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code uint64} field, including tag. - */ - public static int computeUInt64SizeNoTag(final long value) { - return computeRawVarint64Size(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code int64} field, including tag. - */ - public static int computeInt64SizeNoTag(final long value) { - return computeRawVarint64Size(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code int32} field, including tag. - */ - public static int computeInt32SizeNoTag(final int value) { - if (value >= 0) { - return computeRawVarint32Size(value); - } else { - // Must sign-extend. - return 10; - } - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code fixed64} field. - */ - public static int computeFixed64SizeNoTag(final long value) { - return LITTLE_ENDIAN_64_SIZE; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code fixed32} field. - */ - public static int computeFixed32SizeNoTag(final int value) { - return LITTLE_ENDIAN_32_SIZE; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code bool} field. - */ - public static int computeBoolSizeNoTag(final boolean value) { - return 1; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code string} field. - */ - public static int computeStringSizeNoTag(final String value) { - try { - final byte[] bytes = value.getBytes("UTF-8"); - return computeRawVarint32Size(bytes.length) + - bytes.length; - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported."); - } - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code StringUtf8Micro} field. - */ - public static int computeStringUtf8SizeNoTag(final StringUtf8Micro value) { - final byte[] bytes = value.getBytes(); - return computeRawVarint32Size(bytes.length) + - bytes.length; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code group} field. - */ - public static int computeGroupSizeNoTag(final MessageMicro value) { - return value.getCachedSize(); - } - - /** - * Compute the number of bytes that would be needed to encode an embedded - * message field. - */ - public static int computeMessageSizeNoTag(final MessageMicro value) { - final int size = value.getCachedSize(); - return computeRawVarint32Size(size) + size; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code bytes} field. - */ - public static int computeBytesSizeNoTag(final ByteStringMicro value) { - return computeRawVarint32Size(value.size()) + - value.size(); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code uint32} field. - */ - public static int computeUInt32SizeNoTag(final int value) { - return computeRawVarint32Size(value); - } - - /** - * Compute the number of bytes that would be needed to encode an enum field. - * Caller is responsible for converting the enum value to its numeric value. - */ - public static int computeEnumSizeNoTag(final int value) { - return computeRawVarint32Size(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sfixed32} field. - */ - public static int computeSFixed32SizeNoTag(final int value) { - return LITTLE_ENDIAN_32_SIZE; - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sfixed64} field. - */ - public static int computeSFixed64SizeNoTag(final long value) { - return LITTLE_ENDIAN_64_SIZE; - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sint32} field. - */ - public static int computeSInt32SizeNoTag(final int value) { - return computeRawVarint32Size(encodeZigZag32(value)); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sint64} field. - */ - public static int computeSInt64SizeNoTag(final long value) { - return computeRawVarint64Size(encodeZigZag64(value)); - } - - // ================================================================= - - /** - * Internal helper that writes the current buffer to the output. The - * buffer position is reset to its initial value when this returns. - */ - private void refreshBuffer() throws IOException { - if (output == null) { - // We're writing to a single buffer. - throw new OutOfSpaceException(); - } - - // Since we have an output stream, this is our buffer - // and buffer offset == 0 - output.write(buffer, 0, position); - position = 0; - } - - /** - * Flushes the stream and forces any buffered bytes to be written. This - * does not flush the underlying OutputStream. - */ - public void flush() throws IOException { - if (output != null) { - refreshBuffer(); - } - } - - /** - * If writing to a flat array, return the space left in the array. - * Otherwise, throws {@code UnsupportedOperationException}. - */ - public int spaceLeft() { - if (output == null) { - return limit - position; - } else { - throw new UnsupportedOperationException( - "spaceLeft() can only be called on CodedOutputStreams that are " + - "writing to a flat array."); - } - } - - /** - * Verifies that {@link #spaceLeft()} returns zero. It's common to create - * a byte array that is exactly big enough to hold a message, then write to - * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()} - * after writing verifies that the message was actually as big as expected, - * which can help catch bugs. - */ - public void checkNoSpaceLeft() { - if (spaceLeft() != 0) { - throw new IllegalStateException( - "Did not write as much data as expected."); - } - } - - /** - * If you create a CodedOutputStream around a simple flat array, you must - * not attempt to write more bytes than the array has space. Otherwise, - * this exception will be thrown. - */ - public static class OutOfSpaceException extends IOException { - private static final long serialVersionUID = -6947486886997889499L; - - OutOfSpaceException() { - super("CodedOutputStream was writing to a flat byte array and ran " + - "out of space."); - } - } - - /** Write a single byte. */ - public void writeRawByte(final byte value) throws IOException { - if (position == limit) { - refreshBuffer(); - } - - buffer[position++] = value; - } - - /** Write a single byte, represented by an integer value. */ - public void writeRawByte(final int value) throws IOException { - writeRawByte((byte) value); - } - - /** Write an array of bytes. */ - public void writeRawBytes(final byte[] value) throws IOException { - writeRawBytes(value, 0, value.length); - } - - /** Write part of an array of bytes. */ - public void writeRawBytes(final byte[] value, int offset, int length) - throws IOException { - if (limit - position >= length) { - // We have room in the current buffer. - System.arraycopy(value, offset, buffer, position, length); - position += length; - } else { - // Write extends past current buffer. Fill the rest of this buffer and - // flush. - final int bytesWritten = limit - position; - System.arraycopy(value, offset, buffer, position, bytesWritten); - offset += bytesWritten; - length -= bytesWritten; - position = limit; - refreshBuffer(); - - // Now deal with the rest. - // Since we have an output stream, this is our buffer - // and buffer offset == 0 - if (length <= limit) { - // Fits in new buffer. - System.arraycopy(value, offset, buffer, 0, length); - position = length; - } else { - // Write is very big. Let's do it all at once. - output.write(value, offset, length); - } - } - } - - /** Encode and write a tag. */ - public void writeTag(final int fieldNumber, final int wireType) - throws IOException { - writeRawVarint32(WireFormatMicro.makeTag(fieldNumber, wireType)); - } - - /** Compute the number of bytes that would be needed to encode a tag. */ - public static int computeTagSize(final int fieldNumber) { - return computeRawVarint32Size(WireFormatMicro.makeTag(fieldNumber, 0)); - } - - /** - * Encode and write a varint. {@code value} is treated as - * unsigned, so it won't be sign-extended if negative. - */ - public void writeRawVarint32(int value) throws IOException { - while (true) { - if ((value & ~0x7F) == 0) { - writeRawByte(value); - return; - } else { - writeRawByte((value & 0x7F) | 0x80); - value >>>= 7; - } - } - } - - /** - * Compute the number of bytes that would be needed to encode a varint. - * {@code value} is treated as unsigned, so it won't be sign-extended if - * negative. - */ - public static int computeRawVarint32Size(final int value) { - if ((value & (0xffffffff << 7)) == 0) return 1; - if ((value & (0xffffffff << 14)) == 0) return 2; - if ((value & (0xffffffff << 21)) == 0) return 3; - if ((value & (0xffffffff << 28)) == 0) return 4; - return 5; - } - - /** Encode and write a varint. */ - public void writeRawVarint64(long value) throws IOException { - while (true) { - if ((value & ~0x7FL) == 0) { - writeRawByte((int)value); - return; - } else { - writeRawByte(((int)value & 0x7F) | 0x80); - value >>>= 7; - } - } - } - - /** Compute the number of bytes that would be needed to encode a varint. */ - public static int computeRawVarint64Size(final long value) { - if ((value & (0xffffffffffffffffL << 7)) == 0) return 1; - if ((value & (0xffffffffffffffffL << 14)) == 0) return 2; - if ((value & (0xffffffffffffffffL << 21)) == 0) return 3; - if ((value & (0xffffffffffffffffL << 28)) == 0) return 4; - if ((value & (0xffffffffffffffffL << 35)) == 0) return 5; - if ((value & (0xffffffffffffffffL << 42)) == 0) return 6; - if ((value & (0xffffffffffffffffL << 49)) == 0) return 7; - if ((value & (0xffffffffffffffffL << 56)) == 0) return 8; - if ((value & (0xffffffffffffffffL << 63)) == 0) return 9; - return 10; - } - - /** Write a little-endian 32-bit integer. */ - public void writeRawLittleEndian32(final int value) throws IOException { - writeRawByte((value ) & 0xFF); - writeRawByte((value >> 8) & 0xFF); - writeRawByte((value >> 16) & 0xFF); - writeRawByte((value >> 24) & 0xFF); - } - - public static final int LITTLE_ENDIAN_32_SIZE = 4; - - /** Write a little-endian 64-bit integer. */ - public void writeRawLittleEndian64(final long value) throws IOException { - writeRawByte((int)(value ) & 0xFF); - writeRawByte((int)(value >> 8) & 0xFF); - writeRawByte((int)(value >> 16) & 0xFF); - writeRawByte((int)(value >> 24) & 0xFF); - writeRawByte((int)(value >> 32) & 0xFF); - writeRawByte((int)(value >> 40) & 0xFF); - writeRawByte((int)(value >> 48) & 0xFF); - writeRawByte((int)(value >> 56) & 0xFF); - } - - public static final int LITTLE_ENDIAN_64_SIZE = 8; - - /** - * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n A signed 32-bit integer. - * @return An unsigned 32-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - */ - public static int encodeZigZag32(final int n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 31); - } - - /** - * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n A signed 64-bit integer. - * @return An unsigned 64-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - */ - public static long encodeZigZag64(final long n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 63); - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java b/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java deleted file mode 100644 index 050f99b..0000000 --- a/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java +++ /dev/null @@ -1,93 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.IOException; - -/** - * Thrown when a protocol message being parsed is invalid in some way, - * e.g. it contains a malformed varint or a negative byte length. - * - * @author kenton@google.com Kenton Varda - */ -public class InvalidProtocolBufferMicroException extends IOException { - private static final long serialVersionUID = -1616151763072450476L; - - public InvalidProtocolBufferMicroException(final String description) { - super(description); - } - - static InvalidProtocolBufferMicroException truncatedMessage() { - return new InvalidProtocolBufferMicroException( - "While parsing a protocol message, the input ended unexpectedly " + - "in the middle of a field. This could mean either than the " + - "input has been truncated or that an embedded message " + - "misreported its own length."); - } - - static InvalidProtocolBufferMicroException negativeSize() { - return new InvalidProtocolBufferMicroException( - "CodedInputStream encountered an embedded string or message " + - "which claimed to have negative size."); - } - - static InvalidProtocolBufferMicroException malformedVarint() { - return new InvalidProtocolBufferMicroException( - "CodedInputStream encountered a malformed varint."); - } - - static InvalidProtocolBufferMicroException invalidTag() { - return new InvalidProtocolBufferMicroException( - "Protocol message contained an invalid tag (zero)."); - } - - static InvalidProtocolBufferMicroException invalidEndTag() { - return new InvalidProtocolBufferMicroException( - "Protocol message end-group tag did not match expected tag."); - } - - static InvalidProtocolBufferMicroException invalidWireType() { - return new InvalidProtocolBufferMicroException( - "Protocol message tag had invalid wire type."); - } - - static InvalidProtocolBufferMicroException recursionLimitExceeded() { - return new InvalidProtocolBufferMicroException( - "Protocol message had too many levels of nesting. May be malicious. " + - "Use CodedInputStream.setRecursionLimit() to increase the depth limit."); - } - - static InvalidProtocolBufferMicroException sizeLimitExceeded() { - return new InvalidProtocolBufferMicroException( - "Protocol message was too large. May be malicious. " + - "Use CodedInputStream.setSizeLimit() to increase the size limit."); - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/MessageMicro.java b/java/src/main/java/com/google/protobuf/micro/MessageMicro.java deleted file mode 100644 index 0c02793..0000000 --- a/java/src/main/java/com/google/protobuf/micro/MessageMicro.java +++ /dev/null @@ -1,136 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import com.google.protobuf.micro.CodedOutputStreamMicro; -import java.io.IOException; - -/** - * Abstract interface implemented by Protocol Message objects. - * - * @author wink@google.com Wink Saville - */ -public abstract class MessageMicro { - /** - * Get the number of bytes required to encode this message. - * Returns the cached size or calls getSerializedSize which - * sets the cached size. This is used internally when serializing - * so the size is only computed once. If a member is modified - * then this could be stale call getSerializedSize if in doubt. - */ - abstract public int getCachedSize(); - - /** - * Computes the number of bytes required to encode this message. - * The size is cached and the cached result can be retrieved - * using getCachedSize(). - */ - abstract public int getSerializedSize(); - - /** - * Serializes the message and writes it to {@code output}. This does not - * flush or close the stream. - */ - abstract public void writeTo(CodedOutputStreamMicro output) throws java.io.IOException; - - /** - * Parse {@code input} as a message of this type and merge it with the - * message being built. - */ - abstract public MessageMicro mergeFrom(final CodedInputStreamMicro input) throws IOException; - - /** - * Serialize to a byte array. - * @return byte array with the serialized data. - */ - public byte[] toByteArray() { - final byte[] result = new byte[getSerializedSize()]; - toByteArray(result, 0, result.length); - return result; - } - - /** - * Serialize to a byte array starting at offset through length. The - * method getSerializedSize must have been called prior to calling - * this method so the proper length is know. If an attempt to - * write more than length bytes OutOfSpaceException will be thrown - * and if length bytes are not written then IllegalStateException - * is thrown. - * @return byte array with the serialized data. - */ - public void toByteArray(byte [] data, int offset, int length) { - try { - final CodedOutputStreamMicro output = CodedOutputStreamMicro.newInstance(data, offset, length); - writeTo(output); - output.checkNoSpaceLeft(); - } catch (IOException e) { - throw new RuntimeException("Serializing to a byte array threw an IOException " - + "(should never happen)."); - } - } - - /** - * Parse {@code data} as a message of this type and merge it with the - * message being built. - */ - public MessageMicro mergeFrom(final byte[] data) throws InvalidProtocolBufferMicroException { - return mergeFrom(data, 0, data.length); - } - - /** - * Parse {@code data} as a message of this type and merge it with the - * message being built. - */ - public MessageMicro mergeFrom(final byte[] data, final int off, final int len) - throws InvalidProtocolBufferMicroException { - try { - final CodedInputStreamMicro input = CodedInputStreamMicro.newInstance(data, off, len); - mergeFrom(input); - input.checkLastTagWas(0); - return this; - } catch (InvalidProtocolBufferMicroException e) { - throw e; - } catch (IOException e) { - throw new RuntimeException("Reading from a byte array threw an IOException (should " - + "never happen)."); - } - } - - /** - * Called by subclasses to parse an unknown field. - * @return {@code true} unless the tag is an end-group tag. - */ - protected boolean parseUnknownField( - final CodedInputStreamMicro input, - final int tag) throws IOException { - return input.skipField(tag); - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java b/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java deleted file mode 100644 index d8a88bd..0000000 --- a/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java +++ /dev/null @@ -1,87 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -/** - * This class is used internally by the Protocol Buffer library and generated - * message implementations. It is public only because those generated messages - * do not reside in the {@code protobuf} package. Others should not use this - * class directly. - * - * This class contains constants and helper functions useful for dealing with - * the Protocol Buffer wire format. - * - * @author kenton@google.com Kenton Varda - */ -public final class WireFormatMicro { - // Do not allow instantiation. - private WireFormatMicro() {} - - static final int WIRETYPE_VARINT = 0; - static final int WIRETYPE_FIXED64 = 1; - static final int WIRETYPE_LENGTH_DELIMITED = 2; - static final int WIRETYPE_START_GROUP = 3; - static final int WIRETYPE_END_GROUP = 4; - static final int WIRETYPE_FIXED32 = 5; - - static final int TAG_TYPE_BITS = 3; - static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1; - - /** Given a tag value, determines the wire type (the lower 3 bits). */ - static int getTagWireType(final int tag) { - return tag & TAG_TYPE_MASK; - } - - /** Given a tag value, determines the field number (the upper 29 bits). */ - public static int getTagFieldNumber(final int tag) { - return tag >>> TAG_TYPE_BITS; - } - - /** Makes a tag value given a field number and wire type. */ - static int makeTag(final int fieldNumber, final int wireType) { - return (fieldNumber << TAG_TYPE_BITS) | wireType; - } - - // Field numbers for feilds in MessageSet wire format. - static final int MESSAGE_SET_ITEM = 1; - static final int MESSAGE_SET_TYPE_ID = 2; - static final int MESSAGE_SET_MESSAGE = 3; - - // Tag numbers. - static final int MESSAGE_SET_ITEM_TAG = - makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP); - static final int MESSAGE_SET_ITEM_END_TAG = - makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP); - static final int MESSAGE_SET_TYPE_ID_TAG = - makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT); - static final int MESSAGE_SET_MESSAGE_TAG = - makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED); -} diff --git a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java index 2c59fd0..c44d660 100644 --- a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java +++ b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java @@ -38,6 +38,7 @@ import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestPackedTypes; import protobuf_unittest.UnittestProto.TestRequired; import protobuf_unittest.UnittestProto.TestRequiredForeign; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; import junit.framework.TestCase; @@ -238,6 +239,43 @@ public class AbstractMessageTest extends TestCase { TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); } + public void testUnpackedSerialization() throws Exception { + Message abstractMessage = + new AbstractMessageWrapper(TestUtil.getUnpackedSet()); + + TestUtil.assertUnpackedFieldsSet( + TestUnpackedTypes.parseFrom(abstractMessage.toByteString())); + + assertEquals(TestUtil.getUnpackedSet().toByteString(), + abstractMessage.toByteString()); + } + + public void testParsePackedToUnpacked() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet( + (TestUnpackedTypes) message.wrappedMessage); + } + + public void testParseUnpackedToPacked() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); + } + + public void testUnpackedParsing() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet( + (TestUnpackedTypes) message.wrappedMessage); + } + public void testOptimizedForSize() throws Exception { // We're mostly only checking that this class was compiled successfully. TestOptimizedForSize message = diff --git a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java index 850b8aa..6acd322 100644 --- a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java +++ b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java @@ -434,6 +434,7 @@ public class CodedInputStreamTest extends TestCase { new SmallBlockInputStream(new byte[256], 8)); input.setSizeLimit(16); input.readRawBytes(16); + assertEquals(16, input.getTotalBytesRead()); try { input.readRawByte(); @@ -443,7 +444,10 @@ public class CodedInputStreamTest extends TestCase { } input.resetSizeCounter(); + assertEquals(0, input.getTotalBytesRead()); input.readRawByte(); // No exception thrown. + input.resetSizeCounter(); + assertEquals(0, input.getTotalBytesRead()); try { input.readRawBytes(16); // Hits limit again. @@ -477,10 +481,27 @@ public class CodedInputStreamTest extends TestCase { public void testReadFromSlice() throws Exception { byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5); + assertEquals(0, in.getTotalBytesRead()); for (int i = 3; i < 8; i++) { assertEquals(i, in.readRawByte()); + assertEquals(i-2, in.getTotalBytesRead()); } // eof assertEquals(0, in.readTag()); + assertEquals(5, in.getTotalBytesRead()); + } + + public void testInvalidTag() throws Exception { + // Any tag number which corresponds to field number zero is invalid and + // should throw InvalidProtocolBufferException. + for (int i = 0; i < 8; i++) { + try { + CodedInputStream.newInstance(bytes(i)).readTag(); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals(InvalidProtocolBufferException.invalidTag().getMessage(), + e.getMessage()); + } + } } } diff --git a/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/src/test/java/com/google/protobuf/DescriptorsTest.java index c5c38b2..f41d070 100644 --- a/java/src/test/java/com/google/protobuf/DescriptorsTest.java +++ b/java/src/test/java/com/google/protobuf/DescriptorsTest.java @@ -30,6 +30,10 @@ package com.google.protobuf; +import com.google.protobuf.DescriptorProtos.DescriptorProto; +import com.google.protobuf.DescriptorProtos.FieldDescriptorProto; +import com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import com.google.protobuf.Descriptors.DescriptorValidationException; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; @@ -63,6 +67,22 @@ import java.util.Collections; * @author kenton@google.com Kenton Varda */ public class DescriptorsTest extends TestCase { + + // Regression test for bug where referencing a FieldDescriptor.Type value + // before a FieldDescriptorProto.Type value would yield a + // ExceptionInInitializerError. + private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL; + + public void testFieldTypeEnumMapping() throws Exception { + assertEquals(FieldDescriptor.Type.values().length, + FieldDescriptorProto.Type.values().length); + for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) { + FieldDescriptorProto.Type protoType = type.toProto(); + assertEquals("TYPE_" + type.name(), protoType.name()); + assertEquals(type, FieldDescriptor.Type.valueOf(protoType)); + } + } + public void testFileDescriptor() throws Exception { FileDescriptor file = UnittestProto.getDescriptor(); @@ -405,4 +425,35 @@ public class DescriptorsTest extends TestCase { UnittestEnormousDescriptor.getDescriptor() .toProto().getSerializedSize() > 65536); } + + /** + * Tests that the DescriptorValidationException works as intended. + */ + public void testDescriptorValidatorException() throws Exception { + FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addMessageType(DescriptorProto.newBuilder() + .setName("Foo") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_INT32) + .setName("foo") + .setNumber(1) + .setDefaultValue("invalid") + .build()) + .build()) + .build(); + try { + Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, + new FileDescriptor[0]); + fail("DescriptorValidationException expected"); + } catch (DescriptorValidationException e) { + // Expected; check that the error message contains some useful hints + assertTrue(e.getMessage().indexOf("foo") != -1); + assertTrue(e.getMessage().indexOf("Foo") != -1); + assertTrue(e.getMessage().indexOf("invalid") != -1); + assertTrue(e.getCause() instanceof NumberFormatException); + assertTrue(e.getCause().getMessage().indexOf("invalid") != -1); + } + } } diff --git a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java index cdf60c5..73c71f3 100644 --- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -39,6 +39,8 @@ import protobuf_unittest.UnittestProto.ForeignEnum; import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; +import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; import protobuf_unittest.MultipleFilesTestProto; import protobuf_unittest.MessageWithNoOuter; import protobuf_unittest.EnumWithNoOuter; @@ -303,8 +305,15 @@ public class GeneratedMessageTest extends TestCase { TestUtil.assertClear(TestAllTypes.getDefaultInstance()); TestUtil.assertClear(TestAllTypes.newBuilder().build()); - assertEquals("\u1234", - TestExtremeDefaultValues.getDefaultInstance().getUtf8String()); + TestExtremeDefaultValues message = + TestExtremeDefaultValues.getDefaultInstance(); + assertEquals("\u1234", message.getUtf8String()); + assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble()); + assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble()); + assertTrue(Double.isNaN(message.getNanDouble())); + assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat()); + assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat()); + assertTrue(Float.isNaN(message.getNanFloat())); } public void testReflectionGetters() throws Exception { @@ -361,6 +370,20 @@ public class GeneratedMessageTest extends TestCase { assertTrue(map.findValueByNumber(12345) == null); } + public void testParsePackedToUnpacked() throws Exception { + TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); + TestUnpackedTypes message = + builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet(message); + } + + public void testParseUnpackedToPacked() throws Exception { + TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); + TestPackedTypes message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertPackedFieldsSet(message); + } + // ================================================================= // Extensions. @@ -615,4 +638,12 @@ public class GeneratedMessageTest extends TestCase { UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48); assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51); } + + public void testRecursiveMessageDefaultInstance() throws Exception { + UnittestProto.TestRecursiveMessage message = + UnittestProto.TestRecursiveMessage.getDefaultInstance(); + assertTrue(message != null); + assertTrue(message.getA() != null); + assertTrue(message.getA() == message); + } } diff --git a/java/src/test/java/com/google/protobuf/LiteTest.java b/java/src/test/java/com/google/protobuf/LiteTest.java index 9dd730c..728bad9 100644 --- a/java/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/src/test/java/com/google/protobuf/LiteTest.java @@ -83,7 +83,7 @@ public class LiteTest extends TestCase { public void testLiteExtensions() throws Exception { // TODO(kenton): Unlike other features of the lite library, extensions are // implemented completely differently from the regular library. We - // need to test them more thoroughly, once they are fully-implemented. + // should probably test them more thoroughly. TestAllExtensionsLite message = TestAllExtensionsLite.newBuilder() @@ -104,6 +104,8 @@ public class LiteTest extends TestCase { UnittestLite.optionalInt32ExtensionLite)); assertEquals(1, message2.getExtensionCount( UnittestLite.repeatedStringExtensionLite)); + assertEquals(1, message2.getExtension( + UnittestLite.repeatedStringExtensionLite).size()); assertEquals("hello", message2.getExtension( UnittestLite.repeatedStringExtensionLite, 0)); assertEquals(TestAllTypesLite.NestedEnum.BAZ, message2.getExtension( diff --git a/java/src/test/java/com/google/protobuf/MicroTest.java b/java/src/test/java/com/google/protobuf/MicroTest.java deleted file mode 100644 index ebfccc2..0000000 --- a/java/src/test/java/com/google/protobuf/MicroTest.java +++ /dev/null @@ -1,2138 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf; - -import com.google.protobuf.micro.MicroOuterClass; -import com.google.protobuf.micro.MicroOuterClass.TestAllTypesMicro; -import com.google.protobuf.micro.RecursiveMessageMicro; -import com.google.protobuf.micro.SimpleMessageMicro; -import com.google.protobuf.micro.StringUtf8; -import com.google.protobuf.micro.StringUtf8Micro; -import com.google.protobuf.micro.UnittestImportMicro; -import com.google.protobuf.micro.ByteStringMicro; - -import junit.framework.TestCase; - -/** - * Test micro runtime. - * - * @author wink@google.com Wink Saville - */ -public class MicroTest extends TestCase { - public void setUp() throws Exception { - } - - public void testSimpleMessageMicro() throws Exception { - SimpleMessageMicro msg = new SimpleMessageMicro(); - assertFalse(msg.hasD()); - assertEquals(123, msg.getD()); - assertFalse(msg.hasNestedMsg()); - assertEquals(null, msg.getNestedMsg()); - assertFalse(msg.hasDefaultNestedEnum()); - assertEquals(SimpleMessageMicro.BAZ, msg.getDefaultNestedEnum()); - - msg.setD(456); - assertTrue(msg.hasD()); - assertEquals(456, msg.getD()); - msg.clearD() - .setD(456); - assertTrue(msg.hasD()); - - SimpleMessageMicro.NestedMessage nestedMsg = new SimpleMessageMicro.NestedMessage() - .setBb(2); - assertTrue(nestedMsg.hasBb()); - assertEquals(2, nestedMsg.getBb()); - msg.setNestedMsg(nestedMsg); - assertTrue(msg.hasNestedMsg()); - assertEquals(2, msg.getNestedMsg().getBb()); - - msg.setDefaultNestedEnum(SimpleMessageMicro.BAR); - assertTrue(msg.hasDefaultNestedEnum()); - assertEquals(SimpleMessageMicro.BAR, msg.getDefaultNestedEnum()); - - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - SimpleMessageMicro newMsg = SimpleMessageMicro.parseFrom(result); - assertTrue(newMsg.hasD()); - assertTrue(newMsg.hasNestedMsg()); - assertTrue(newMsg.hasDefaultNestedEnum()); - assertEquals(456, newMsg.getD()); - assertEquals(2, msg.getNestedMsg().getBb()); - assertEquals(SimpleMessageMicro.BAR, msg.getDefaultNestedEnum()); - } - - public void testRecursiveMessageMicro() throws Exception { - RecursiveMessageMicro msg = new RecursiveMessageMicro(); - assertFalse(msg.hasId()); - assertFalse(msg.hasNestedMessage()); - assertFalse(msg.hasOptionalRecursiveMessageMicro()); - assertEquals(0, msg.getRepeatedRecursiveMessageMicroCount()); - - RecursiveMessageMicro msg1 = new RecursiveMessageMicro(); - msg1.setId(1); - assertEquals(1, msg1.getId()); - RecursiveMessageMicro msg2 = new RecursiveMessageMicro(); - msg2.setId(2); - RecursiveMessageMicro msg3 = new RecursiveMessageMicro(); - msg3.setId(3); - - RecursiveMessageMicro.NestedMessage nestedMsg = new RecursiveMessageMicro.NestedMessage(); - nestedMsg.setA(msg1); - assertEquals(1, nestedMsg.getA().getId()); - - msg.setId(0); - msg.setNestedMessage(nestedMsg); - msg.setOptionalRecursiveMessageMicro(msg2); - msg.addRepeatedRecursiveMessageMicro(msg3); - - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - RecursiveMessageMicro newMsg = RecursiveMessageMicro.parseFrom(result); - assertTrue(newMsg.hasId()); - assertTrue(newMsg.hasNestedMessage()); - assertTrue(newMsg.hasOptionalRecursiveMessageMicro()); - assertEquals(1, newMsg.getRepeatedRecursiveMessageMicroCount()); - - assertEquals(0, newMsg.getId()); - assertEquals(1, newMsg.getNestedMessage().getA().getId()); - assertEquals(2, newMsg.getOptionalRecursiveMessageMicro().getId()); - assertEquals(3, newMsg.getRepeatedRecursiveMessageMicro(0).getId()); - } - - public void testMicroRequiredInt32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasId()); - assertFalse(msg.isInitialized()); - msg.setId(123); - assertTrue(msg.hasId()); - assertTrue(msg.isInitialized()); - assertEquals(123, msg.getId()); - msg.clearId(); - assertFalse(msg.hasId()); - assertFalse(msg.isInitialized()); - msg.clearId() - .setId(456); - assertTrue(msg.hasId()); - msg.clear(); - assertFalse(msg.hasId()); - assertFalse(msg.isInitialized()); - - msg.setId(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasId()); - assertTrue(newMsg.isInitialized()); - assertEquals(123, newMsg.getId()); - } - - public void testMicroOptionalInt32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalInt32()); - msg.setOptionalInt32(123); - assertTrue(msg.hasOptionalInt32()); - assertEquals(123, msg.getOptionalInt32()); - msg.clearOptionalInt32(); - assertFalse(msg.hasOptionalInt32()); - msg.clearOptionalInt32() - .setOptionalInt32(456); - assertTrue(msg.hasOptionalInt32()); - msg.clear(); - assertFalse(msg.hasOptionalInt32()); - - msg.setOptionalInt32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalInt32()); - assertEquals(123, newMsg.getOptionalInt32()); - } - - public void testMicroOptionalInt64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalInt64()); - msg.setOptionalInt64(123); - assertTrue(msg.hasOptionalInt64()); - assertEquals(123, msg.getOptionalInt64()); - msg.clearOptionalInt64(); - assertFalse(msg.hasOptionalInt64()); - msg.clearOptionalInt64() - .setOptionalInt64(456); - assertTrue(msg.hasOptionalInt64()); - msg.clear(); - assertFalse(msg.hasOptionalInt64()); - - msg.setOptionalInt64(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalInt64()); - assertEquals(123, newMsg.getOptionalInt64()); - } - - public void testMicroOptionalUint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalUint32()); - msg.setOptionalUint32(123); - assertTrue(msg.hasOptionalUint32()); - assertEquals(123, msg.getOptionalUint32()); - msg.clearOptionalUint32(); - assertFalse(msg.hasOptionalUint32()); - msg.clearOptionalUint32() - .setOptionalUint32(456); - assertTrue(msg.hasOptionalUint32()); - msg.clear(); - assertFalse(msg.hasOptionalUint32()); - - msg.setOptionalUint32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalUint32()); - assertEquals(123, newMsg.getOptionalUint32()); - } - - public void testMicroOptionalUint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalUint64()); - msg.setOptionalUint64(123); - assertTrue(msg.hasOptionalUint64()); - assertEquals(123, msg.getOptionalUint64()); - msg.clearOptionalUint64(); - assertFalse(msg.hasOptionalUint64()); - msg.clearOptionalUint64() - .setOptionalUint64(456); - assertTrue(msg.hasOptionalUint64()); - msg.clear(); - assertFalse(msg.hasOptionalUint64()); - - msg.setOptionalUint64(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalUint64()); - assertEquals(123, newMsg.getOptionalUint64()); - } - - public void testMicroOptionalSint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSint32()); - msg.setOptionalSint32(123); - assertTrue(msg.hasOptionalSint32()); - assertEquals(123, msg.getOptionalSint32()); - msg.clearOptionalSint32(); - assertFalse(msg.hasOptionalSint32()); - msg.clearOptionalSint32() - .setOptionalSint32(456); - assertTrue(msg.hasOptionalSint32()); - msg.clear(); - assertFalse(msg.hasOptionalSint32()); - - msg.setOptionalSint32(-123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSint32()); - assertEquals(-123, newMsg.getOptionalSint32()); - } - - public void testMicroOptionalSint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSint64()); - msg.setOptionalSint64(123); - assertTrue(msg.hasOptionalSint64()); - assertEquals(123, msg.getOptionalSint64()); - msg.clearOptionalSint64(); - assertFalse(msg.hasOptionalSint64()); - msg.clearOptionalSint64() - .setOptionalSint64(456); - assertTrue(msg.hasOptionalSint64()); - msg.clear(); - assertFalse(msg.hasOptionalSint64()); - - msg.setOptionalSint64(-123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSint64()); - assertEquals(-123, newMsg.getOptionalSint64()); - } - - public void testMicroOptionalFixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalFixed32()); - msg.setOptionalFixed32(123); - assertTrue(msg.hasOptionalFixed32()); - assertEquals(123, msg.getOptionalFixed32()); - msg.clearOptionalFixed32(); - assertFalse(msg.hasOptionalFixed32()); - msg.clearOptionalFixed32() - .setOptionalFixed32(456); - assertTrue(msg.hasOptionalFixed32()); - msg.clear(); - assertFalse(msg.hasOptionalFixed32()); - - msg.setOptionalFixed32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalFixed32()); - assertEquals(123, newMsg.getOptionalFixed32()); - } - - public void testMicroOptionalFixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalFixed64()); - msg.setOptionalFixed64(123); - assertTrue(msg.hasOptionalFixed64()); - assertEquals(123, msg.getOptionalFixed64()); - msg.clearOptionalFixed64(); - assertFalse(msg.hasOptionalFixed64()); - msg.clearOptionalFixed64() - .setOptionalFixed64(456); - assertTrue(msg.hasOptionalFixed64()); - msg.clear(); - assertFalse(msg.hasOptionalFixed64()); - - msg.setOptionalFixed64(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalFixed64()); - assertEquals(123, newMsg.getOptionalFixed64()); - } - public void testMicroOptionalSfixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSfixed32()); - msg.setOptionalSfixed32(123); - assertTrue(msg.hasOptionalSfixed32()); - assertEquals(123, msg.getOptionalSfixed32()); - msg.clearOptionalSfixed32(); - assertFalse(msg.hasOptionalSfixed32()); - msg.clearOptionalSfixed32() - .setOptionalSfixed32(456); - assertTrue(msg.hasOptionalSfixed32()); - msg.clear(); - assertFalse(msg.hasOptionalSfixed32()); - - msg.setOptionalSfixed32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSfixed32()); - assertEquals(123, newMsg.getOptionalSfixed32()); - } - - public void testMicroOptionalSfixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSfixed64()); - msg.setOptionalSfixed64(123); - assertTrue(msg.hasOptionalSfixed64()); - assertEquals(123, msg.getOptionalSfixed64()); - msg.clearOptionalSfixed64(); - assertFalse(msg.hasOptionalSfixed64()); - msg.clearOptionalSfixed64() - .setOptionalSfixed64(456); - assertTrue(msg.hasOptionalSfixed64()); - msg.clear(); - assertFalse(msg.hasOptionalSfixed64()); - - msg.setOptionalSfixed64(-123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSfixed64()); - assertEquals(-123, newMsg.getOptionalSfixed64()); - } - - public void testMicroOptionalFloat() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalFloat()); - msg.setOptionalFloat(123f); - assertTrue(msg.hasOptionalFloat()); - assertTrue(123.0f == msg.getOptionalFloat()); - msg.clearOptionalFloat(); - assertFalse(msg.hasOptionalFloat()); - msg.clearOptionalFloat() - .setOptionalFloat(456.0f); - assertTrue(msg.hasOptionalFloat()); - msg.clear(); - assertFalse(msg.hasOptionalFloat()); - - msg.setOptionalFloat(-123.456f); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalFloat()); - assertTrue(-123.456f == newMsg.getOptionalFloat()); - } - - public void testMicroOptionalDouble() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalDouble()); - msg.setOptionalDouble(123); - assertTrue(msg.hasOptionalDouble()); - assertTrue(123.0 == msg.getOptionalDouble()); - msg.clearOptionalDouble(); - assertFalse(msg.hasOptionalDouble()); - msg.clearOptionalDouble() - .setOptionalDouble(456.0); - assertTrue(msg.hasOptionalDouble()); - msg.clear(); - assertFalse(msg.hasOptionalDouble()); - - msg.setOptionalDouble(-123.456); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalDouble()); - assertTrue(-123.456 == newMsg.getOptionalDouble()); - } - - public void testMicroOptionalBool() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalBool()); - msg.setOptionalBool(true); - assertTrue(msg.hasOptionalBool()); - assertEquals(true, msg.getOptionalBool()); - msg.clearOptionalBool(); - assertFalse(msg.hasOptionalBool()); - msg.clearOptionalBool() - .setOptionalBool(true); - assertTrue(msg.hasOptionalBool()); - msg.clear(); - assertFalse(msg.hasOptionalBool()); - - msg.setOptionalBool(false); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalBool()); - assertEquals(false, newMsg.getOptionalBool()); - } - - public void testMicroOptionalString() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalString()); - msg.setOptionalString("hello"); - assertTrue(msg.hasOptionalString()); - assertEquals("hello", msg.getOptionalString()); - msg.clearOptionalString(); - assertFalse(msg.hasOptionalString()); - msg.clearOptionalString() - .setOptionalString("hello"); - assertTrue(msg.hasOptionalString()); - msg.clear(); - assertFalse(msg.hasOptionalString()); - - msg.setOptionalString("bye"); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalString()); - assertEquals("bye", newMsg.getOptionalString()); - } - - public void testMicroOptionalBytes() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalBytes()); - msg.setOptionalBytes(ByteStringMicro.copyFromUtf8("hello")); - assertTrue(msg.hasOptionalBytes()); - assertEquals("hello", msg.getOptionalBytes().toStringUtf8()); - msg.clearOptionalBytes(); - assertFalse(msg.hasOptionalBytes()); - msg.clearOptionalBytes() - .setOptionalBytes(ByteStringMicro.copyFromUtf8("hello")); - assertTrue(msg.hasOptionalBytes()); - msg.clear(); - assertFalse(msg.hasOptionalBytes()); - - msg.setOptionalBytes(ByteStringMicro.copyFromUtf8("bye")); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalBytes()); - assertEquals("bye", newMsg.getOptionalBytes().toStringUtf8()); - } - - public void testMicroOptionalGroup() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.OptionalGroup grp = new TestAllTypesMicro.OptionalGroup(); - grp.setA(1); - assertFalse(msg.hasOptionalGroup()); - msg.setOptionalGroup(grp); - assertTrue(msg.hasOptionalGroup()); - assertEquals(1, msg.getOptionalGroup().getA()); - msg.clearOptionalGroup(); - assertFalse(msg.hasOptionalGroup()); - msg.clearOptionalGroup() - .setOptionalGroup(new TestAllTypesMicro.OptionalGroup().setA(2)); - assertTrue(msg.hasOptionalGroup()); - msg.clear(); - assertFalse(msg.hasOptionalGroup()); - - msg.setOptionalGroup(grp); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalGroup()); - assertEquals(1, newMsg.getOptionalGroup().getA()); - } - - public void testMicroOptionalNestedMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.NestedMessage nestedMsg = new TestAllTypesMicro.NestedMessage(); - nestedMsg.setBb(1); - assertFalse(msg.hasOptionalNestedMessage()); - msg.setOptionalNestedMessage(nestedMsg); - assertTrue(msg.hasOptionalNestedMessage()); - assertEquals(1, msg.getOptionalNestedMessage().getBb()); - msg.clearOptionalNestedMessage(); - assertFalse(msg.hasOptionalNestedMessage()); - msg.clearOptionalNestedMessage() - .setOptionalNestedMessage(new TestAllTypesMicro.NestedMessage().setBb(2)); - assertTrue(msg.hasOptionalNestedMessage()); - msg.clear(); - assertFalse(msg.hasOptionalNestedMessage()); - - msg.setOptionalNestedMessage(nestedMsg); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalNestedMessage()); - assertEquals(1, newMsg.getOptionalNestedMessage().getBb()); - } - - public void testMicroOptionalForeignMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - MicroOuterClass.ForeignMessageMicro foreignMsg = - new MicroOuterClass.ForeignMessageMicro(); - assertFalse(foreignMsg.hasC()); - foreignMsg.setC(1); - assertTrue(foreignMsg.hasC()); - assertFalse(msg.hasOptionalForeignMessage()); - msg.setOptionalForeignMessage(foreignMsg); - assertTrue(msg.hasOptionalForeignMessage()); - assertEquals(1, msg.getOptionalForeignMessage().getC()); - msg.clearOptionalForeignMessage(); - assertFalse(msg.hasOptionalForeignMessage()); - msg.clearOptionalForeignMessage() - .setOptionalForeignMessage(new MicroOuterClass.ForeignMessageMicro().setC(2)); - assertTrue(msg.hasOptionalForeignMessage()); - msg.clear(); - assertFalse(msg.hasOptionalForeignMessage()); - - msg.setOptionalForeignMessage(foreignMsg); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalForeignMessage()); - assertEquals(1, newMsg.getOptionalForeignMessage().getC()); - } - - public void testMicroOptionalImportMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - UnittestImportMicro.ImportMessageMicro importMsg = - new UnittestImportMicro.ImportMessageMicro(); - assertFalse(importMsg.hasD()); - importMsg.setD(1); - assertTrue(importMsg.hasD()); - assertFalse(msg.hasOptionalImportMessage()); - msg.setOptionalImportMessage(importMsg); - assertTrue(msg.hasOptionalImportMessage()); - assertEquals(1, msg.getOptionalImportMessage().getD()); - msg.clearOptionalImportMessage(); - assertFalse(msg.hasOptionalImportMessage()); - msg.clearOptionalImportMessage() - .setOptionalImportMessage(new UnittestImportMicro.ImportMessageMicro().setD(2)); - assertTrue(msg.hasOptionalImportMessage()); - msg.clear(); - assertFalse(msg.hasOptionalImportMessage()); - - msg.setOptionalImportMessage(importMsg); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalImportMessage()); - assertEquals(1, newMsg.getOptionalImportMessage().getD()); - } - - public void testMicroOptionalNestedEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.setOptionalNestedEnum(TestAllTypesMicro.BAR); - assertTrue(msg.hasOptionalNestedEnum()); - assertEquals(TestAllTypesMicro.BAR, msg.getOptionalNestedEnum()); - msg.clearOptionalNestedEnum(); - assertFalse(msg.hasOptionalNestedEnum()); - msg.clearOptionalNestedEnum() - .setOptionalNestedEnum(TestAllTypesMicro.BAZ); - assertTrue(msg.hasOptionalNestedEnum()); - msg.clear(); - assertFalse(msg.hasOptionalNestedEnum()); - - msg.setOptionalNestedEnum(TestAllTypesMicro.BAR); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalNestedEnum()); - assertEquals(TestAllTypesMicro.BAR, newMsg.getOptionalNestedEnum()); - } - - public void testMicroOptionalForeignEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertTrue(msg.hasOptionalForeignEnum()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, - msg.getOptionalForeignEnum()); - msg.clearOptionalForeignEnum(); - assertFalse(msg.hasOptionalForeignEnum()); - msg.clearOptionalForeignEnum() - .setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAZ); - assertTrue(msg.hasOptionalForeignEnum()); - msg.clear(); - assertFalse(msg.hasOptionalForeignEnum()); - - msg.setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalForeignEnum()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, - newMsg.getOptionalForeignEnum()); - } - - public void testMicroOptionalImportEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertTrue(msg.hasOptionalImportEnum()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, - msg.getOptionalImportEnum()); - msg.clearOptionalImportEnum(); - assertFalse(msg.hasOptionalImportEnum()); - msg.clearOptionalImportEnum() - .setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAZ); - assertTrue(msg.hasOptionalImportEnum()); - msg.clear(); - assertFalse(msg.hasOptionalImportEnum()); - - msg.setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalImportEnum()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, - newMsg.getOptionalImportEnum()); - } - - public void testMicroOptionalStringPiece() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalStringPiece()); - msg.setOptionalStringPiece("hello"); - assertTrue(msg.hasOptionalStringPiece()); - assertEquals("hello", msg.getOptionalStringPiece()); - msg.clearOptionalStringPiece(); - assertFalse(msg.hasOptionalStringPiece()); - msg.clearOptionalStringPiece() - .setOptionalStringPiece("hello"); - assertTrue(msg.hasOptionalStringPiece()); - msg.clear(); - assertFalse(msg.hasOptionalStringPiece()); - - msg.setOptionalStringPiece("bye"); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalStringPiece()); - assertEquals("bye", newMsg.getOptionalStringPiece()); - } - - public void testMicroOptionalCord() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalCord()); - msg.setOptionalCord("hello"); - assertTrue(msg.hasOptionalCord()); - assertEquals("hello", msg.getOptionalCord()); - msg.clearOptionalCord(); - assertFalse(msg.hasOptionalCord()); - msg.clearOptionalCord() - .setOptionalCord("hello"); - assertTrue(msg.hasOptionalCord()); - msg.clear(); - assertFalse(msg.hasOptionalCord()); - - msg.setOptionalCord("bye"); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalCord()); - assertEquals("bye", newMsg.getOptionalCord()); - } - - public void testMicroRepeatedInt32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedInt32Count()); - msg.addRepeatedInt32(123); - assertEquals(1, msg.getRepeatedInt32Count()); - assertEquals(123, msg.getRepeatedInt32(0)); - msg.addRepeatedInt32(456); - assertEquals(2, msg.getRepeatedInt32Count()); - assertEquals(123, msg.getRepeatedInt32(0)); - assertEquals(456, msg.getRepeatedInt32(1)); - msg.setRepeatedInt32(0, 789); - assertEquals(2, msg.getRepeatedInt32Count()); - assertEquals(789, msg.getRepeatedInt32(0)); - assertEquals(456, msg.getRepeatedInt32(1)); - msg.clearRepeatedInt32(); - assertEquals(0, msg.getRepeatedInt32Count()); - msg.clearRepeatedInt32() - .addRepeatedInt32(456); - assertEquals(1, msg.getRepeatedInt32Count()); - assertEquals(456, msg.getRepeatedInt32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedInt32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedInt32(123); - assertEquals(1, msg.getRepeatedInt32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedInt32Count()); - assertEquals(123, newMsg.getRepeatedInt32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedInt32(123) - .addRepeatedInt32(456); - assertEquals(2, msg.getRepeatedInt32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedInt32Count()); - assertEquals(123, newMsg.getRepeatedInt32(0)); - assertEquals(456, newMsg.getRepeatedInt32(1)); - } - - public void testMicroRepeatedInt64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedInt64Count()); - msg.addRepeatedInt64(123); - assertEquals(1, msg.getRepeatedInt64Count()); - assertEquals(123, msg.getRepeatedInt64(0)); - msg.addRepeatedInt64(456); - assertEquals(2, msg.getRepeatedInt64Count()); - assertEquals(123, msg.getRepeatedInt64(0)); - assertEquals(456, msg.getRepeatedInt64(1)); - msg.setRepeatedInt64(0, 789); - assertEquals(2, msg.getRepeatedInt64Count()); - assertEquals(789, msg.getRepeatedInt64(0)); - assertEquals(456, msg.getRepeatedInt64(1)); - msg.clearRepeatedInt64(); - assertEquals(0, msg.getRepeatedInt64Count()); - msg.clearRepeatedInt64() - .addRepeatedInt64(456); - assertEquals(1, msg.getRepeatedInt64Count()); - assertEquals(456, msg.getRepeatedInt64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedInt64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedInt64(123); - assertEquals(1, msg.getRepeatedInt64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedInt64Count()); - assertEquals(123, newMsg.getRepeatedInt64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedInt64(123) - .addRepeatedInt64(456); - assertEquals(2, msg.getRepeatedInt64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedInt64Count()); - assertEquals(123, newMsg.getRepeatedInt64(0)); - assertEquals(456, newMsg.getRepeatedInt64(1)); - } - - public void testMicroRepeatedUint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedUint32Count()); - msg.addRepeatedUint32(123); - assertEquals(1, msg.getRepeatedUint32Count()); - assertEquals(123, msg.getRepeatedUint32(0)); - msg.addRepeatedUint32(456); - assertEquals(2, msg.getRepeatedUint32Count()); - assertEquals(123, msg.getRepeatedUint32(0)); - assertEquals(456, msg.getRepeatedUint32(1)); - msg.setRepeatedUint32(0, 789); - assertEquals(2, msg.getRepeatedUint32Count()); - assertEquals(789, msg.getRepeatedUint32(0)); - assertEquals(456, msg.getRepeatedUint32(1)); - msg.clearRepeatedUint32(); - assertEquals(0, msg.getRepeatedUint32Count()); - msg.clearRepeatedUint32() - .addRepeatedUint32(456); - assertEquals(1, msg.getRepeatedUint32Count()); - assertEquals(456, msg.getRepeatedUint32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedUint32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedUint32(123); - assertEquals(1, msg.getRepeatedUint32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedUint32Count()); - assertEquals(123, newMsg.getRepeatedUint32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedUint32(123) - .addRepeatedUint32(456); - assertEquals(2, msg.getRepeatedUint32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedUint32Count()); - assertEquals(123, newMsg.getRepeatedUint32(0)); - assertEquals(456, newMsg.getRepeatedUint32(1)); - } - - public void testMicroRepeatedUint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedUint64Count()); - msg.addRepeatedUint64(123); - assertEquals(1, msg.getRepeatedUint64Count()); - assertEquals(123, msg.getRepeatedUint64(0)); - msg.addRepeatedUint64(456); - assertEquals(2, msg.getRepeatedUint64Count()); - assertEquals(123, msg.getRepeatedUint64(0)); - assertEquals(456, msg.getRepeatedUint64(1)); - msg.setRepeatedUint64(0, 789); - assertEquals(2, msg.getRepeatedUint64Count()); - assertEquals(789, msg.getRepeatedUint64(0)); - assertEquals(456, msg.getRepeatedUint64(1)); - msg.clearRepeatedUint64(); - assertEquals(0, msg.getRepeatedUint64Count()); - msg.clearRepeatedUint64() - .addRepeatedUint64(456); - assertEquals(1, msg.getRepeatedUint64Count()); - assertEquals(456, msg.getRepeatedUint64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedUint64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedUint64(123); - assertEquals(1, msg.getRepeatedUint64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedUint64Count()); - assertEquals(123, newMsg.getRepeatedUint64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedUint64(123) - .addRepeatedUint64(456); - assertEquals(2, msg.getRepeatedUint64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedUint64Count()); - assertEquals(123, newMsg.getRepeatedUint64(0)); - assertEquals(456, newMsg.getRepeatedUint64(1)); - } - - public void testMicroRepeatedSint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSint32Count()); - msg.addRepeatedSint32(123); - assertEquals(1, msg.getRepeatedSint32Count()); - assertEquals(123, msg.getRepeatedSint32(0)); - msg.addRepeatedSint32(456); - assertEquals(2, msg.getRepeatedSint32Count()); - assertEquals(123, msg.getRepeatedSint32(0)); - assertEquals(456, msg.getRepeatedSint32(1)); - msg.setRepeatedSint32(0, 789); - assertEquals(2, msg.getRepeatedSint32Count()); - assertEquals(789, msg.getRepeatedSint32(0)); - assertEquals(456, msg.getRepeatedSint32(1)); - msg.clearRepeatedSint32(); - assertEquals(0, msg.getRepeatedSint32Count()); - msg.clearRepeatedSint32() - .addRepeatedSint32(456); - assertEquals(1, msg.getRepeatedSint32Count()); - assertEquals(456, msg.getRepeatedSint32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSint32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSint32(123); - assertEquals(1, msg.getRepeatedSint32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 4); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSint32Count()); - assertEquals(123, newMsg.getRepeatedSint32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSint32(123) - .addRepeatedSint32(456); - assertEquals(2, msg.getRepeatedSint32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 8); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSint32Count()); - assertEquals(123, newMsg.getRepeatedSint32(0)); - assertEquals(456, newMsg.getRepeatedSint32(1)); - } - - public void testMicroRepeatedSint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSint64Count()); - msg.addRepeatedSint64(123); - assertEquals(1, msg.getRepeatedSint64Count()); - assertEquals(123, msg.getRepeatedSint64(0)); - msg.addRepeatedSint64(456); - assertEquals(2, msg.getRepeatedSint64Count()); - assertEquals(123, msg.getRepeatedSint64(0)); - assertEquals(456, msg.getRepeatedSint64(1)); - msg.setRepeatedSint64(0, 789); - assertEquals(2, msg.getRepeatedSint64Count()); - assertEquals(789, msg.getRepeatedSint64(0)); - assertEquals(456, msg.getRepeatedSint64(1)); - msg.clearRepeatedSint64(); - assertEquals(0, msg.getRepeatedSint64Count()); - msg.clearRepeatedSint64() - .addRepeatedSint64(456); - assertEquals(1, msg.getRepeatedSint64Count()); - assertEquals(456, msg.getRepeatedSint64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSint64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSint64(123); - assertEquals(1, msg.getRepeatedSint64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 4); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSint64Count()); - assertEquals(123, newMsg.getRepeatedSint64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSint64(123) - .addRepeatedSint64(456); - assertEquals(2, msg.getRepeatedSint64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 8); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSint64Count()); - assertEquals(123, newMsg.getRepeatedSint64(0)); - assertEquals(456, newMsg.getRepeatedSint64(1)); - } - - public void testMicroRepeatedFixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedFixed32Count()); - msg.addRepeatedFixed32(123); - assertEquals(1, msg.getRepeatedFixed32Count()); - assertEquals(123, msg.getRepeatedFixed32(0)); - msg.addRepeatedFixed32(456); - assertEquals(2, msg.getRepeatedFixed32Count()); - assertEquals(123, msg.getRepeatedFixed32(0)); - assertEquals(456, msg.getRepeatedFixed32(1)); - msg.setRepeatedFixed32(0, 789); - assertEquals(2, msg.getRepeatedFixed32Count()); - assertEquals(789, msg.getRepeatedFixed32(0)); - assertEquals(456, msg.getRepeatedFixed32(1)); - msg.clearRepeatedFixed32(); - assertEquals(0, msg.getRepeatedFixed32Count()); - msg.clearRepeatedFixed32() - .addRepeatedFixed32(456); - assertEquals(1, msg.getRepeatedFixed32Count()); - assertEquals(456, msg.getRepeatedFixed32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedFixed32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedFixed32(123); - assertEquals(1, msg.getRepeatedFixed32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedFixed32Count()); - assertEquals(123, newMsg.getRepeatedFixed32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedFixed32(123) - .addRepeatedFixed32(456); - assertEquals(2, msg.getRepeatedFixed32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 12); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedFixed32Count()); - assertEquals(123, newMsg.getRepeatedFixed32(0)); - assertEquals(456, newMsg.getRepeatedFixed32(1)); - } - - public void testMicroRepeatedFixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedFixed64Count()); - msg.addRepeatedFixed64(123); - assertEquals(1, msg.getRepeatedFixed64Count()); - assertEquals(123, msg.getRepeatedFixed64(0)); - msg.addRepeatedFixed64(456); - assertEquals(2, msg.getRepeatedFixed64Count()); - assertEquals(123, msg.getRepeatedFixed64(0)); - assertEquals(456, msg.getRepeatedFixed64(1)); - msg.setRepeatedFixed64(0, 789); - assertEquals(2, msg.getRepeatedFixed64Count()); - assertEquals(789, msg.getRepeatedFixed64(0)); - assertEquals(456, msg.getRepeatedFixed64(1)); - msg.clearRepeatedFixed64(); - assertEquals(0, msg.getRepeatedFixed64Count()); - msg.clearRepeatedFixed64() - .addRepeatedFixed64(456); - assertEquals(1, msg.getRepeatedFixed64Count()); - assertEquals(456, msg.getRepeatedFixed64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedFixed64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedFixed64(123); - assertEquals(1, msg.getRepeatedFixed64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedFixed64Count()); - assertEquals(123, newMsg.getRepeatedFixed64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedFixed64(123) - .addRepeatedFixed64(456); - assertEquals(2, msg.getRepeatedFixed64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 20); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedFixed64Count()); - assertEquals(123, newMsg.getRepeatedFixed64(0)); - assertEquals(456, newMsg.getRepeatedFixed64(1)); - } - - public void testMicroRepeatedSfixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSfixed32Count()); - msg.addRepeatedSfixed32(123); - assertEquals(1, msg.getRepeatedSfixed32Count()); - assertEquals(123, msg.getRepeatedSfixed32(0)); - msg.addRepeatedSfixed32(456); - assertEquals(2, msg.getRepeatedSfixed32Count()); - assertEquals(123, msg.getRepeatedSfixed32(0)); - assertEquals(456, msg.getRepeatedSfixed32(1)); - msg.setRepeatedSfixed32(0, 789); - assertEquals(2, msg.getRepeatedSfixed32Count()); - assertEquals(789, msg.getRepeatedSfixed32(0)); - assertEquals(456, msg.getRepeatedSfixed32(1)); - msg.clearRepeatedSfixed32(); - assertEquals(0, msg.getRepeatedSfixed32Count()); - msg.clearRepeatedSfixed32() - .addRepeatedSfixed32(456); - assertEquals(1, msg.getRepeatedSfixed32Count()); - assertEquals(456, msg.getRepeatedSfixed32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSfixed32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSfixed32(123); - assertEquals(1, msg.getRepeatedSfixed32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSfixed32Count()); - assertEquals(123, newMsg.getRepeatedSfixed32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSfixed32(123) - .addRepeatedSfixed32(456); - assertEquals(2, msg.getRepeatedSfixed32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 12); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSfixed32Count()); - assertEquals(123, newMsg.getRepeatedSfixed32(0)); - assertEquals(456, newMsg.getRepeatedSfixed32(1)); - } - - public void testMicroRepeatedSfixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSfixed64Count()); - msg.addRepeatedSfixed64(123); - assertEquals(1, msg.getRepeatedSfixed64Count()); - assertEquals(123, msg.getRepeatedSfixed64(0)); - msg.addRepeatedSfixed64(456); - assertEquals(2, msg.getRepeatedSfixed64Count()); - assertEquals(123, msg.getRepeatedSfixed64(0)); - assertEquals(456, msg.getRepeatedSfixed64(1)); - msg.setRepeatedSfixed64(0, 789); - assertEquals(2, msg.getRepeatedSfixed64Count()); - assertEquals(789, msg.getRepeatedSfixed64(0)); - assertEquals(456, msg.getRepeatedSfixed64(1)); - msg.clearRepeatedSfixed64(); - assertEquals(0, msg.getRepeatedSfixed64Count()); - msg.clearRepeatedSfixed64() - .addRepeatedSfixed64(456); - assertEquals(1, msg.getRepeatedSfixed64Count()); - assertEquals(456, msg.getRepeatedSfixed64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSfixed64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSfixed64(123); - assertEquals(1, msg.getRepeatedSfixed64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSfixed64Count()); - assertEquals(123, newMsg.getRepeatedSfixed64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSfixed64(123) - .addRepeatedSfixed64(456); - assertEquals(2, msg.getRepeatedSfixed64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 20); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSfixed64Count()); - assertEquals(123, newMsg.getRepeatedSfixed64(0)); - assertEquals(456, newMsg.getRepeatedSfixed64(1)); - } - - public void testMicroRepeatedFloat() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedFloatCount()); - msg.addRepeatedFloat(123f); - assertEquals(1, msg.getRepeatedFloatCount()); - assertTrue(123f == msg.getRepeatedFloat(0)); - msg.addRepeatedFloat(456f); - assertEquals(2, msg.getRepeatedFloatCount()); - assertTrue(123f == msg.getRepeatedFloat(0)); - assertTrue(456f == msg.getRepeatedFloat(1)); - msg.setRepeatedFloat(0, 789f); - assertEquals(2, msg.getRepeatedFloatCount()); - assertTrue(789f == msg.getRepeatedFloat(0)); - assertTrue(456f == msg.getRepeatedFloat(1)); - msg.clearRepeatedFloat(); - assertEquals(0, msg.getRepeatedFloatCount()); - msg.clearRepeatedFloat() - .addRepeatedFloat(456f); - assertEquals(1, msg.getRepeatedFloatCount()); - assertTrue(456f == msg.getRepeatedFloat(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedFloatCount()); - - // Test 1 entry - msg.clear() - .addRepeatedFloat(123f); - assertEquals(1, msg.getRepeatedFloatCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedFloatCount()); - assertTrue(123f == newMsg.getRepeatedFloat(0)); - - // Test 2 entries - msg.clear() - .addRepeatedFloat(123f) - .addRepeatedFloat(456f); - assertEquals(2, msg.getRepeatedFloatCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 12); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedFloatCount()); - assertTrue(123f == newMsg.getRepeatedFloat(0)); - assertTrue(456f == newMsg.getRepeatedFloat(1)); - } - - public void testMicroRepeatedDouble() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedDoubleCount()); - msg.addRepeatedDouble(123.0); - assertEquals(1, msg.getRepeatedDoubleCount()); - assertTrue(123.0 == msg.getRepeatedDouble(0)); - msg.addRepeatedDouble(456.0); - assertEquals(2, msg.getRepeatedDoubleCount()); - assertTrue(123.0 == msg.getRepeatedDouble(0)); - assertTrue(456.0 == msg.getRepeatedDouble(1)); - msg.setRepeatedDouble(0, 789.0); - assertEquals(2, msg.getRepeatedDoubleCount()); - assertTrue(789.0 == msg.getRepeatedDouble(0)); - assertTrue(456.0 == msg.getRepeatedDouble(1)); - msg.clearRepeatedDouble(); - assertEquals(0, msg.getRepeatedDoubleCount()); - msg.clearRepeatedDouble() - .addRepeatedDouble(456.0); - assertEquals(1, msg.getRepeatedDoubleCount()); - assertTrue(456.0 == msg.getRepeatedDouble(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedDoubleCount()); - - // Test 1 entry - msg.clear() - .addRepeatedDouble(123.0); - assertEquals(1, msg.getRepeatedDoubleCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedDoubleCount()); - assertTrue(123.0 == newMsg.getRepeatedDouble(0)); - - // Test 2 entries - msg.clear() - .addRepeatedDouble(123.0) - .addRepeatedDouble(456.0); - assertEquals(2, msg.getRepeatedDoubleCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 20); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedDoubleCount()); - assertTrue(123.0 == newMsg.getRepeatedDouble(0)); - assertTrue(456.0 == newMsg.getRepeatedDouble(1)); - } - - public void testMicroRepeatedBool() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedBoolCount()); - msg.addRepeatedBool(true); - assertEquals(1, msg.getRepeatedBoolCount()); - assertEquals(true, msg.getRepeatedBool(0)); - msg.addRepeatedBool(false); - assertEquals(2, msg.getRepeatedBoolCount()); - assertEquals(true, msg.getRepeatedBool(0)); - assertEquals(false, msg.getRepeatedBool(1)); - msg.setRepeatedBool(0, false); - assertEquals(2, msg.getRepeatedBoolCount()); - assertEquals(false, msg.getRepeatedBool(0)); - assertEquals(false, msg.getRepeatedBool(1)); - msg.clearRepeatedBool(); - assertEquals(0, msg.getRepeatedBoolCount()); - msg.clearRepeatedBool() - .addRepeatedBool(true); - assertEquals(1, msg.getRepeatedBoolCount()); - assertEquals(true, msg.getRepeatedBool(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedBoolCount()); - - // Test 1 entry - msg.clear() - .addRepeatedBool(false); - assertEquals(1, msg.getRepeatedBoolCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedBoolCount()); - assertEquals(false, newMsg.getRepeatedBool(0)); - - // Test 2 entries - msg.clear() - .addRepeatedBool(true) - .addRepeatedBool(false); - assertEquals(2, msg.getRepeatedBoolCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedBoolCount()); - assertEquals(true, newMsg.getRepeatedBool(0)); - assertEquals(false, newMsg.getRepeatedBool(1)); - } - - public void testMicroRepeatedString() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedStringCount()); - msg.addRepeatedString("hello"); - assertEquals(1, msg.getRepeatedStringCount()); - assertEquals("hello", msg.getRepeatedString(0)); - msg.addRepeatedString("bye"); - assertEquals(2, msg.getRepeatedStringCount()); - assertEquals("hello", msg.getRepeatedString(0)); - assertEquals("bye", msg.getRepeatedString(1)); - msg.setRepeatedString(0, "boo"); - assertEquals(2, msg.getRepeatedStringCount()); - assertEquals("boo", msg.getRepeatedString(0)); - assertEquals("bye", msg.getRepeatedString(1)); - msg.clearRepeatedString(); - assertEquals(0, msg.getRepeatedStringCount()); - msg.clearRepeatedString() - .addRepeatedString("hello"); - assertEquals(1, msg.getRepeatedStringCount()); - assertEquals("hello", msg.getRepeatedString(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedStringCount()); - - // Test 1 entry and an empty string - msg.clear() - .addRepeatedString(""); - assertEquals(1, msg.getRepeatedStringCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedStringCount()); - assertEquals("", newMsg.getRepeatedString(0)); - - // Test 2 entries - msg.clear() - .addRepeatedString("hello") - .addRepeatedString("world"); - assertEquals(2, msg.getRepeatedStringCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedStringCount()); - assertEquals("hello", newMsg.getRepeatedString(0)); - assertEquals("world", newMsg.getRepeatedString(1)); - } - - public void testMicroRepeatedBytes() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedBytesCount()); - msg.addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello")); - assertEquals(1, msg.getRepeatedBytesCount()); - assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8()); - msg.addRepeatedBytes(ByteStringMicro.copyFromUtf8("bye")); - assertEquals(2, msg.getRepeatedBytesCount()); - assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8()); - assertEquals("bye", msg.getRepeatedBytes(1).toStringUtf8()); - msg.setRepeatedBytes(0, ByteStringMicro.copyFromUtf8("boo")); - assertEquals(2, msg.getRepeatedBytesCount()); - assertEquals("boo", msg.getRepeatedBytes(0).toStringUtf8()); - assertEquals("bye", msg.getRepeatedBytes(1).toStringUtf8()); - msg.clearRepeatedBytes(); - assertEquals(0, msg.getRepeatedBytesCount()); - msg.clearRepeatedBytes() - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello")); - assertEquals(1, msg.getRepeatedBytesCount()); - assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8()); - msg.clear(); - assertEquals(0, msg.getRepeatedBytesCount()); - - // Test 1 entry and an empty byte array can be serialized - msg.clear() - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("")); - assertEquals(1, msg.getRepeatedBytesCount()); - assertEquals("", msg.getRepeatedBytes(0).toStringUtf8()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedBytesCount()); - assertEquals("", newMsg.getRepeatedBytes(0).toStringUtf8()); - - // Test 2 entries - msg.clear() - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello")) - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("world")); - assertEquals(2, msg.getRepeatedBytesCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedBytesCount()); - assertEquals("hello", newMsg.getRepeatedBytes(0).toStringUtf8()); - assertEquals("world", newMsg.getRepeatedBytes(1).toStringUtf8()); - } - - public void testMicroRepeatedGroup() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.RepeatedGroup group0 = - new TestAllTypesMicro.RepeatedGroup().setA(0); - TestAllTypesMicro.RepeatedGroup group1 = - new TestAllTypesMicro.RepeatedGroup().setA(1); - TestAllTypesMicro.RepeatedGroup group2 = - new TestAllTypesMicro.RepeatedGroup().setA(2); - - msg.addRepeatedGroup(group0); - assertEquals(1, msg.getRepeatedGroupCount()); - assertEquals(0, msg.getRepeatedGroup(0).getA()); - msg.addRepeatedGroup(group1); - assertEquals(2, msg.getRepeatedGroupCount()); - assertEquals(0, msg.getRepeatedGroup(0).getA()); - assertEquals(1, msg.getRepeatedGroup(1).getA()); - msg.setRepeatedGroup(0, group2); - assertEquals(2, msg.getRepeatedGroupCount()); - assertEquals(2, msg.getRepeatedGroup(0).getA()); - assertEquals(1, msg.getRepeatedGroup(1).getA()); - msg.clearRepeatedGroup(); - assertEquals(0, msg.getRepeatedGroupCount()); - msg.clearRepeatedGroup() - .addRepeatedGroup(group1); - assertEquals(1, msg.getRepeatedGroupCount()); - assertEquals(1, msg.getRepeatedGroup(0).getA()); - msg.clear(); - assertEquals(0, msg.getRepeatedGroupCount()); - - // Test 1 entry - msg.clear() - .addRepeatedGroup(group0); - assertEquals(1, msg.getRepeatedGroupCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedGroupCount()); - assertEquals(0, newMsg.getRepeatedGroup(0).getA()); - - // Test 2 entries - msg.clear() - .addRepeatedGroup(group0) - .addRepeatedGroup(group1); - assertEquals(2, msg.getRepeatedGroupCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 14); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedGroupCount()); - assertEquals(0, newMsg.getRepeatedGroup(0).getA()); - assertEquals(1, newMsg.getRepeatedGroup(1).getA()); - } - - - public void testMicroRepeatedNestedMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.NestedMessage nestedMsg0 = - new TestAllTypesMicro.NestedMessage().setBb(0); - TestAllTypesMicro.NestedMessage nestedMsg1 = - new TestAllTypesMicro.NestedMessage().setBb(1); - TestAllTypesMicro.NestedMessage nestedMsg2 = - new TestAllTypesMicro.NestedMessage().setBb(2); - - msg.addRepeatedNestedMessage(nestedMsg0); - assertEquals(1, msg.getRepeatedNestedMessageCount()); - assertEquals(0, msg.getRepeatedNestedMessage(0).getBb()); - msg.addRepeatedNestedMessage(nestedMsg1); - assertEquals(2, msg.getRepeatedNestedMessageCount()); - assertEquals(0, msg.getRepeatedNestedMessage(0).getBb()); - assertEquals(1, msg.getRepeatedNestedMessage(1).getBb()); - msg.setRepeatedNestedMessage(0, nestedMsg2); - assertEquals(2, msg.getRepeatedNestedMessageCount()); - assertEquals(2, msg.getRepeatedNestedMessage(0).getBb()); - assertEquals(1, msg.getRepeatedNestedMessage(1).getBb()); - msg.clearRepeatedNestedMessage(); - assertEquals(0, msg.getRepeatedNestedMessageCount()); - msg.clearRepeatedNestedMessage() - .addRepeatedNestedMessage(nestedMsg1); - assertEquals(1, msg.getRepeatedNestedMessageCount()); - assertEquals(1, msg.getRepeatedNestedMessage(0).getBb()); - msg.clear(); - assertEquals(0, msg.getRepeatedNestedMessageCount()); - - // Test 1 entry - msg.clear() - .addRepeatedNestedMessage(nestedMsg0); - assertEquals(1, msg.getRepeatedNestedMessageCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedNestedMessageCount()); - assertEquals(0, newMsg.getRepeatedNestedMessage(0).getBb()); - - // Test 2 entries - msg.clear() - .addRepeatedNestedMessage(nestedMsg0) - .addRepeatedNestedMessage(nestedMsg1); - assertEquals(2, msg.getRepeatedNestedMessageCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedNestedMessageCount()); - assertEquals(0, newMsg.getRepeatedNestedMessage(0).getBb()); - assertEquals(1, newMsg.getRepeatedNestedMessage(1).getBb()); - } - - public void testMicroRepeatedForeignMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - MicroOuterClass.ForeignMessageMicro foreignMsg0 = - new MicroOuterClass.ForeignMessageMicro().setC(0); - MicroOuterClass.ForeignMessageMicro foreignMsg1 = - new MicroOuterClass.ForeignMessageMicro().setC(1); - MicroOuterClass.ForeignMessageMicro foreignMsg2 = - new MicroOuterClass.ForeignMessageMicro().setC(2); - - msg.addRepeatedForeignMessage(foreignMsg0); - assertEquals(1, msg.getRepeatedForeignMessageCount()); - assertEquals(0, msg.getRepeatedForeignMessage(0).getC()); - msg.addRepeatedForeignMessage(foreignMsg1); - assertEquals(2, msg.getRepeatedForeignMessageCount()); - assertEquals(0, msg.getRepeatedForeignMessage(0).getC()); - assertEquals(1, msg.getRepeatedForeignMessage(1).getC()); - msg.setRepeatedForeignMessage(0, foreignMsg2); - assertEquals(2, msg.getRepeatedForeignMessageCount()); - assertEquals(2, msg.getRepeatedForeignMessage(0).getC()); - assertEquals(1, msg.getRepeatedForeignMessage(1).getC()); - msg.clearRepeatedForeignMessage(); - assertEquals(0, msg.getRepeatedForeignMessageCount()); - msg.clearRepeatedForeignMessage() - .addRepeatedForeignMessage(foreignMsg1); - assertEquals(1, msg.getRepeatedForeignMessageCount()); - assertEquals(1, msg.getRepeatedForeignMessage(0).getC()); - msg.clear(); - assertEquals(0, msg.getRepeatedForeignMessageCount()); - - // Test 1 entry - msg.clear() - .addRepeatedForeignMessage(foreignMsg0); - assertEquals(1, msg.getRepeatedForeignMessageCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedForeignMessageCount()); - assertEquals(0, newMsg.getRepeatedForeignMessage(0).getC()); - - // Test 2 entries - msg.clear() - .addRepeatedForeignMessage(foreignMsg0) - .addRepeatedForeignMessage(foreignMsg1); - assertEquals(2, msg.getRepeatedForeignMessageCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedForeignMessageCount()); - assertEquals(0, newMsg.getRepeatedForeignMessage(0).getC()); - assertEquals(1, newMsg.getRepeatedForeignMessage(1).getC()); - } - - public void testMicroRepeatedImportMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - UnittestImportMicro.ImportMessageMicro importMsg0 = - new UnittestImportMicro.ImportMessageMicro().setD(0); - UnittestImportMicro.ImportMessageMicro importMsg1 = - new UnittestImportMicro.ImportMessageMicro().setD(1); - UnittestImportMicro.ImportMessageMicro importMsg2 = - new UnittestImportMicro.ImportMessageMicro().setD(2); - - msg.addRepeatedImportMessage(importMsg0); - assertEquals(1, msg.getRepeatedImportMessageCount()); - assertEquals(0, msg.getRepeatedImportMessage(0).getD()); - msg.addRepeatedImportMessage(importMsg1); - assertEquals(2, msg.getRepeatedImportMessageCount()); - assertEquals(0, msg.getRepeatedImportMessage(0).getD()); - assertEquals(1, msg.getRepeatedImportMessage(1).getD()); - msg.setRepeatedImportMessage(0, importMsg2); - assertEquals(2, msg.getRepeatedImportMessageCount()); - assertEquals(2, msg.getRepeatedImportMessage(0).getD()); - assertEquals(1, msg.getRepeatedImportMessage(1).getD()); - msg.clearRepeatedImportMessage(); - assertEquals(0, msg.getRepeatedImportMessageCount()); - msg.clearRepeatedImportMessage() - .addRepeatedImportMessage(importMsg1); - assertEquals(1, msg.getRepeatedImportMessageCount()); - assertEquals(1, msg.getRepeatedImportMessage(0).getD()); - msg.clear(); - assertEquals(0, msg.getRepeatedImportMessageCount()); - - // Test 1 entry - msg.clear() - .addRepeatedImportMessage(importMsg0); - assertEquals(1, msg.getRepeatedImportMessageCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedImportMessageCount()); - assertEquals(0, newMsg.getRepeatedImportMessage(0).getD()); - - // Test 2 entries - msg.clear() - .addRepeatedImportMessage(importMsg0) - .addRepeatedImportMessage(importMsg1); - assertEquals(2, msg.getRepeatedImportMessageCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedImportMessageCount()); - assertEquals(0, newMsg.getRepeatedImportMessage(0).getD()); - assertEquals(1, newMsg.getRepeatedImportMessage(1).getD()); - } - - public void testMicroRepeatedNestedEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.addRepeatedNestedEnum(TestAllTypesMicro.FOO); - assertEquals(1, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - msg.addRepeatedNestedEnum(TestAllTypesMicro.BAR); - assertEquals(2, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1)); - msg.setRepeatedNestedEnum(0, TestAllTypesMicro.BAZ); - assertEquals(2, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.BAZ, msg.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1)); - msg.clearRepeatedNestedEnum(); - assertEquals(0, msg.getRepeatedNestedEnumCount()); - msg.clearRepeatedNestedEnum() - .addRepeatedNestedEnum(TestAllTypesMicro.BAR); - assertEquals(1, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedNestedEnumCount()); - - // Test 1 entry - msg.clear() - .addRepeatedNestedEnum(TestAllTypesMicro.FOO); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - - // Test 2 entries - msg.clear() - .addRepeatedNestedEnum(TestAllTypesMicro.FOO) - .addRepeatedNestedEnum(TestAllTypesMicro.BAR); - assertEquals(2, msg.getRepeatedNestedEnumCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1)); - } - - public void testMicroRepeatedForeignEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO); - assertEquals(1, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - msg.addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertEquals(2, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1)); - msg.setRepeatedForeignEnum(0, MicroOuterClass.FOREIGN_MICRO_BAZ); - assertEquals(2, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAZ, msg.getRepeatedForeignEnum(0)); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1)); - msg.clearRepeatedForeignEnum(); - assertEquals(0, msg.getRepeatedForeignEnumCount()); - msg.clearRepeatedForeignEnum() - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertEquals(1, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedForeignEnumCount()); - - // Test 1 entry - msg.clear() - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - - // Test 2 entries - msg.clear() - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO) - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertEquals(2, msg.getRepeatedForeignEnumCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1)); - } - - public void testMicroRepeatedImportEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO); - assertEquals(1, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - msg.addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertEquals(2, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1)); - msg.setRepeatedImportEnum(0, UnittestImportMicro.IMPORT_MICRO_BAZ); - assertEquals(2, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAZ, msg.getRepeatedImportEnum(0)); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1)); - msg.clearRepeatedImportEnum(); - assertEquals(0, msg.getRepeatedImportEnumCount()); - msg.clearRepeatedImportEnum() - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertEquals(1, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedImportEnumCount()); - - // Test 1 entry - msg.clear() - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - - // Test 2 entries - msg.clear() - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO) - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertEquals(2, msg.getRepeatedImportEnumCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1)); - } - - public void testMicroRepeatedStringPiece() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedStringPieceCount()); - msg.addRepeatedStringPiece("hello"); - assertEquals(1, msg.getRepeatedStringPieceCount()); - assertEquals("hello", msg.getRepeatedStringPiece(0)); - msg.addRepeatedStringPiece("bye"); - assertEquals(2, msg.getRepeatedStringPieceCount()); - assertEquals("hello", msg.getRepeatedStringPiece(0)); - assertEquals("bye", msg.getRepeatedStringPiece(1)); - msg.setRepeatedStringPiece(0, "boo"); - assertEquals(2, msg.getRepeatedStringPieceCount()); - assertEquals("boo", msg.getRepeatedStringPiece(0)); - assertEquals("bye", msg.getRepeatedStringPiece(1)); - msg.clearRepeatedStringPiece(); - assertEquals(0, msg.getRepeatedStringPieceCount()); - msg.clearRepeatedStringPiece() - .addRepeatedStringPiece("hello"); - assertEquals(1, msg.getRepeatedStringPieceCount()); - assertEquals("hello", msg.getRepeatedStringPiece(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedStringPieceCount()); - - // Test 1 entry and an empty string - msg.clear() - .addRepeatedStringPiece(""); - assertEquals(1, msg.getRepeatedStringPieceCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedStringPieceCount()); - assertEquals("", newMsg.getRepeatedStringPiece(0)); - - // Test 2 entries - msg.clear() - .addRepeatedStringPiece("hello") - .addRepeatedStringPiece("world"); - assertEquals(2, msg.getRepeatedStringPieceCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedStringPieceCount()); - assertEquals("hello", newMsg.getRepeatedStringPiece(0)); - assertEquals("world", newMsg.getRepeatedStringPiece(1)); - } - - public void testMicroRepeatedCord() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedCordCount()); - msg.addRepeatedCord("hello"); - assertEquals(1, msg.getRepeatedCordCount()); - assertEquals("hello", msg.getRepeatedCord(0)); - msg.addRepeatedCord("bye"); - assertEquals(2, msg.getRepeatedCordCount()); - assertEquals("hello", msg.getRepeatedCord(0)); - assertEquals("bye", msg.getRepeatedCord(1)); - msg.setRepeatedCord(0, "boo"); - assertEquals(2, msg.getRepeatedCordCount()); - assertEquals("boo", msg.getRepeatedCord(0)); - assertEquals("bye", msg.getRepeatedCord(1)); - msg.clearRepeatedCord(); - assertEquals(0, msg.getRepeatedCordCount()); - msg.clearRepeatedCord() - .addRepeatedCord("hello"); - assertEquals(1, msg.getRepeatedCordCount()); - assertEquals("hello", msg.getRepeatedCord(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedCordCount()); - - // Test 1 entry and an empty string - msg.clear() - .addRepeatedCord(""); - assertEquals(1, msg.getRepeatedCordCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedCordCount()); - assertEquals("", newMsg.getRepeatedCord(0)); - - // Test 2 entries - msg.clear() - .addRepeatedCord("hello") - .addRepeatedCord("world"); - assertEquals(2, msg.getRepeatedCordCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedCordCount()); - assertEquals("hello", newMsg.getRepeatedCord(0)); - assertEquals("world", newMsg.getRepeatedCord(1)); - } - - public void testMicroDefaults() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasDefaultInt32()); - assertEquals(41, msg.getDefaultInt32()); - assertFalse(msg.hasDefaultInt64()); - assertEquals(42, msg.getDefaultInt64()); - assertFalse(msg.hasDefaultUint32()); - assertEquals(43, msg.getDefaultUint32()); - assertFalse(msg.hasDefaultUint64()); - assertEquals(44, msg.getDefaultUint64()); - assertFalse(msg.hasDefaultSint32()); - assertEquals(-45, msg.getDefaultSint32()); - assertFalse(msg.hasDefaultSint64()); - assertEquals(46, msg.getDefaultSint64()); - assertFalse(msg.hasDefaultFixed32()); - assertEquals(47, msg.getDefaultFixed32()); - assertFalse(msg.hasDefaultFixed64()); - assertEquals(48, msg.getDefaultFixed64()); - assertFalse(msg.hasDefaultSfixed32()); - assertEquals(49, msg.getDefaultSfixed32()); - assertFalse(msg.hasDefaultSfixed64()); - assertEquals(-50, msg.getDefaultSfixed64()); - assertFalse(msg.hasDefaultFloat()); - assertTrue(51.5f == msg.getDefaultFloat()); - assertFalse(msg.hasDefaultDouble()); - assertTrue(52.0e3 == msg.getDefaultDouble()); - assertFalse(msg.hasDefaultBool()); - assertEquals(true, msg.getDefaultBool()); - assertFalse(msg.hasDefaultString()); - assertEquals("hello", msg.getDefaultString()); - assertFalse(msg.hasDefaultBytes()); - assertEquals("world", msg.getDefaultBytes().toStringUtf8()); - assertFalse(msg.hasDefaultNestedEnum()); - assertEquals(TestAllTypesMicro.BAR, msg.getDefaultNestedEnum()); - assertFalse(msg.hasDefaultForeignEnum()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getDefaultForeignEnum()); - assertFalse(msg.hasDefaultImportEnum()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getDefaultImportEnum()); - } -} diff --git a/java/src/test/java/com/google/protobuf/PerfTimer.java b/java/src/test/java/com/google/protobuf/PerfTimer.java deleted file mode 100644 index d6df4ff..0000000 --- a/java/src/test/java/com/google/protobuf/PerfTimer.java +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.protobuf; - -import java.util.Arrays; - -/** - * A Performance Timing class that can be used to estimate the amount of time a - * sequence of code takes. The typical code sequence would be as follows:</p> - * <code> - PerfTimer pt = new PerfTimer(); - pt.calibrate(); - pt.timeEachAutomatically(new Runnable() = { - public void run() { - // Add code to time - } - }); - System.out.printf("time per loop=" + pt); - - * The calibrate method determines the overhead of timing the run() method and - * the number of times to call the run() method to have approximately 1% precision - * for timing. The method pt.stats() method will return a string containing some - * statistics tpl, il, ol, min, max, mean, median, stddev and total. - * - * tpl ::= Timer per loop - * min ::= minimum time one call to run() took - * stddev ::= Standard deviation of the collected times - * mean ::= the average time to call run() - * median ::= 1/2 the times were > than this time and 1/2 were less. - * total ::= Sum of the times collected. - * il ::= innerLoops; the number of times run() between each call to start/stop - * ol ::= outerLoops, the number of times start/stop was called - * - * You can also use start/stop/restart to do simple timing: - * - * pt.start(); - * a += 1; - * pt.stop(); - * pt.log("time=" + pt); - * pt.restart(); - * doSomething(); - * pt.stop(); - * System.out.printf("time=" + pt); - * </code> - * - * @author wink@google.com (Wink Saville) - */ -public class PerfTimer { - /** No debug */ - public static final int DEBUG_LEVEL_NONE = 0; - - /** Some debug */ - public static final int DEBUG_LEVEL_SOME = 1; - - /** All debug */ - public static final int DEBUG_LEVEL_ALL = 2; - - /** Timer ticks per microsecond */ - private static final double TICKS_PER_MICROSECOND = 1000.0; - - /** Random number generator */ - java.util.Random rng = new java.util.Random(); - - /** get ticks */ - private static long getTicks() { - return System.nanoTime(); - } - - /** Debug logging */ - private static void log(String s) { - System.out.printf(String.format("[PerfTimer] %s\n", s)); - } - - /** Outer loops for timeEachAutomatically */ - private static final int OUTER_LOOPS = 100; - - /** Thrown if an error occurs while timing */ - public static class PerfTimerException extends RuntimeException { - } - - /** - * Calibration record - */ - public static class CalibrationRec { - /** Runnable overhead */ - public double mRunnableOverheadInMicros = 0.0; - - /** Minimum Threshold value for timeEachAutomaticaly */ - public double mMinThresholdInMicros = 3000.0; - - /** Maximum Threshold value for timeEachAutomaticaly */ - public double mMaxThresholdInMicros = 6000.0; - - /** Desired precision in decimal digits */ - public double mPrecisionInDecimalDigits = 2.0; - - /** - * Default number of retries if the standard deviation ratio is too - * large - */ - public final int mStdDevRetrys = 5; - - /** Default maximum standard deviation radio */ - public final double mMaxStdDevRatio = 0.15; - - /** Number of votes looking for smallest time per loop */ - public final int mVotes = 3; - - /** Convert to string */ - @Override - public String toString() { - return String - .format( - "oh=%.6fus minT=%.6fus maxT=%.6fus prc=%,.3f stdDevRetrys=%d maxStdDevRatio=%.2f votes=%d", - mRunnableOverheadInMicros, mMinThresholdInMicros, - mMaxThresholdInMicros, mPrecisionInDecimalDigits, mStdDevRetrys, - mMaxStdDevRatio, mVotes); - } - } - - /** - * Calibration record - */ - private CalibrationRec mCr; - - /** - * Statistics calculated on the timing data. - */ - public static class Stats { - /** Number of outer loops */ - private int mOuterLoops; - - /** Number of inner loops */ - private int mInnerLoops; - - /** Minimum time in times array */ - private long mMin; - - /** Maximum time in times array */ - private long mMax; - - /** Median value in times array */ - private double mMedian; - - /** The mean (average) of the values in times array */ - private double mMean; - - /** The standard deviation of the values in times array */ - private double mStdDev; - - private int mStdDevTooLargeCount; - - /** Sum of the times in the times array */ - private double mTotal; - - /** Initialize */ - public void init() { - mInnerLoops = 1; - mOuterLoops = 1; - mMin = 0; - mMax = 0; - mMedian = 0; - mMean = 0; - mStdDev = 0; - mStdDevTooLargeCount = 0; - mTotal = 0; - } - - /** Constructor */ - public Stats() { - init(); - } - - /** Set number of inner loops */ - public void setInnerLoops(int loops) { - mInnerLoops = loops; - } - - /** Get number of inner loops */ - public int getInnerLoops() { - return mInnerLoops; - } - - /** Set number of inner loops */ - public void setOuterLoops(int loops) { - mOuterLoops = loops; - } - - /** Get number of inner loops */ - public int getOuterLoops() { - return mOuterLoops; - } - - /** - * Minimum value of collected data in microseconds, valid after analyze. - */ - public double getMinInMicros() { - return mMin / TICKS_PER_MICROSECOND; - } - - /** - * Maximum value of collected data in microseconds, valid after analyze. - */ - public double getMaxInMicros() { - return mMax / TICKS_PER_MICROSECOND; - } - - /** - * Sum of the values of collected data in microseconds, valid after - * analyze. - */ - public double getTotalInMicros() { - return mTotal / TICKS_PER_MICROSECOND; - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getTotalInSecs() { - return mTotal / (TICKS_PER_MICROSECOND * 1000000.0); - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getMeanInMicros() { - return mMean / TICKS_PER_MICROSECOND; - } - - /** Median value of collected data in microseconds, valid after analyze. */ - public double getMedianInMicros() { - return mMedian / TICKS_PER_MICROSECOND; - } - - /** - * Standard deviation of collected data in microseconds, valid after - * analyze. - */ - public double getStdDevInMicros() { - return mStdDev / TICKS_PER_MICROSECOND; - } - - public double getStdDevRatio() { - return mStdDev / mMin; - } - - /** Return true if (mStdDev / mMin) <= maxStdDevRation */ - public boolean stdDevOk(double maxStdDevRatio) { - return getStdDevRatio() <= maxStdDevRatio; - } - - /** Increment StdDevTooLargeCount */ - public void incStdDevTooLargeCount() { - mStdDevTooLargeCount += 1; - } - - /** Return number of times stdDev was not ok */ - public int getStdDevTooLargeCount() { - return mStdDevTooLargeCount; - } - - /** Return time per loop */ - public double getTimePerLoop() { - return mMin / TICKS_PER_MICROSECOND / mInnerLoops; - } - - /** - * Calculate the stats for the data. Note the data in the range will be - * sorted. - * - * @param data - * @param count - */ - public Stats calculate(long data[], int count) { - if (count == 1) { - mMin = mMax = data[0]; - mTotal = mMedian = mMean = data[0]; - mStdDev = 0; - } else if (count > 1) { - Arrays.sort(data, 0, count); - mMin = data[0]; - mMax = data[count - 1]; - if ((count & 1) == 1) { - mMedian = data[((count + 1) / 2) - 1]; - } else { - mMedian = (data[count / 2] + data[(count / 2) - 1]) / 2; - } - mTotal = 0; - double sumSquares = 0; - for (int i = 0; i < count; i++) { - long t = data[i]; - mTotal += t; - sumSquares += t * t; - } - mMean = mTotal / count; - double variance = (sumSquares / count) - (mMean * mMean); - mStdDev = Math.pow(variance, 0.5); - } else { - init(); - } - return this; - } - - /** Convert to string */ - @Override - public String toString() { - double timePerLoop = getTimePerLoop(); - double stdDevPerLoop = mStdDev / TICKS_PER_MICROSECOND / mInnerLoops; - return String.format( - "tpl=%,.6fus stdDev=%,.6fus tpl/stdDev=%.2fpercent min=%,.6fus median=%,.6fus mean=%,.6fus max=%,.6fus total=%,.6fs il=%d, ol=%d tlc=%d", - timePerLoop, stdDevPerLoop, (stdDevPerLoop / timePerLoop) * 100, mMin - / TICKS_PER_MICROSECOND, mMedian / TICKS_PER_MICROSECOND, mMean - / TICKS_PER_MICROSECOND, mMax / TICKS_PER_MICROSECOND, mTotal - / (TICKS_PER_MICROSECOND * 1000000.0), mInnerLoops, mOuterLoops, mStdDevTooLargeCount); - } - } - - /** Statistics */ - private Stats mStats = new Stats(); - - /** Statistics of the clock precision */ - private Stats mClockStats; - - /** Number of items in times array */ - private int mCount; - - /** Array of stop - start times */ - private long mTimes[]; - - /** Time of last started */ - private long mStart; - - /** Sleep a little so we don't look like a hog */ - private void sleep() { - try { - Thread.sleep(0); - } catch (InterruptedException e) { - // Ignore exception - } - } - - /** Empty Runnable used for determining overhead */ - private Runnable mEmptyRunnable = new Runnable() { - public void run() { - } - }; - - /** Initialize */ - private void init(int maxCount, CalibrationRec cr) { - mTimes = new long[maxCount]; - mCr = cr; - reset(); - } - - /** Construct the stop watch */ - public PerfTimer() { - init(10, new CalibrationRec()); - } - - /** Construct setting size of times array */ - public PerfTimer(int maxCount) { - init(maxCount, new CalibrationRec()); - } - - /** Construct the stop watch */ - public PerfTimer(CalibrationRec cr) { - init(10, cr); - } - - /** Construct the stop watch */ - public PerfTimer(int maxCount, CalibrationRec cr) { - init(maxCount, cr); - } - - /** Reset the contents of the times array */ - public PerfTimer reset() { - mCount = 0; - mStats.init(); - return this; - } - - /** Reset and then start the timer */ - public PerfTimer restart() { - reset(); - mStart = getTicks(); - return this; - } - - /** Start timing */ - public PerfTimer start() { - mStart = getTicks(); - return this; - } - - /** - * Record the difference between start and now in the times array - * incrementing count. The time will be stored in the times array if the - * array is not full. - */ - public PerfTimer stop() { - long stop = getTicks(); - if (mCount < mTimes.length) { - mTimes[mCount++] = stop - mStart; - } - return this; - } - - /** - * Time how long it takes to execute runnable.run() innerLoop number of - * times outerLoops number of times. - * - * @param outerLoops - * @param innerLoops - * @param runnable - * @return PerfTimer - */ - public PerfTimer timeEach(Stats stats, int outerLoops, int innerLoops, Runnable runnable) { - reset(); - resize(outerLoops); - stats.setOuterLoops(outerLoops); - stats.setInnerLoops(innerLoops); - for (int i = 0; i < outerLoops; i++) { - start(); - for (int j = 0; j < innerLoops; j++) { - runnable.run(); - } - stop(); - sleep(); - } - return this; - } - - /** - * Time how long it takes to execute runnable.run(). Runs runnable votes - * times and returns the Stats of the fastest run. The actual number times - * that runnable.run() is executes is enough times so that it runs at least - * minThreadholeInMicros but not greater than maxThreadholdInMicro. This - * minimizes the chance that long context switches influence the result. - * - * @param votes is the number of runnable will be executed to determine - * fastest run - * @param outerLoops is the number of of times the inner loop is run - * @param initialInnerLoops is the initial inner loop - * @param maxStdDevRetrys if the maxStdDevRatio is exceeded this number of - * time the PerfTimerException is thrown. - * @param maxStdDevRatio the ratio of the standard deviation of the run and - * the time to run. - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @param runnable is the code to test. - * @return Stats of the fastest run. - */ - public Stats timeEachAutomatically(int votes, int outerLoops, int initialInnerLoops, - double minThresholdInMicros, double maxThresholdInMicros, int maxStdDevRetrys, - double maxStdDevRatio, int debugLevel, Runnable runnable) throws PerfTimerException { - Stats minStats = null; - - for (int v = 0; v < votes; v++) { - boolean successful = false; - Stats stats = new Stats(); - int innerLoops = initialInnerLoops; - - /* Warm up cache */ - timeEach(stats, outerLoops, initialInnerLoops, runnable); - - for (int stdDevRetrys = 0; stdDevRetrys < maxStdDevRetrys; stdDevRetrys++) { - /** - * First time may be long enough - */ - timeEach(stats, outerLoops, innerLoops, runnable); - analyze(stats, mTimes, outerLoops, debugLevel); - double innerLoopTime = stats.getMinInMicros(); - if ((innerLoopTime >= minThresholdInMicros - - ((maxThresholdInMicros - minThresholdInMicros) / 2))) { - if (stats.stdDevOk(maxStdDevRatio)) { - successful = true; - break; - } else { - stats.incStdDevTooLargeCount(); - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format( - "tea: tlc=%d StdDevRatio=%.2f > maxStdDevRatio=%.2f", - stats.getStdDevTooLargeCount(), stats.getStdDevRatio(), - maxStdDevRatio)); - } - } - } else { - /** - * The initial number of loops is too short find the number - * of loops that exceeds maxThresholdInMicros. Then use a - * binary search to find the approriate innerLoop value that - * is between min/maxThreshold. - */ - innerLoops *= 10; - int maxInnerLoops = innerLoops; - int minInnerLoops = 1; - boolean binarySearch = false; - for (int i = 0; i < 10; i++) { - timeEach(stats, outerLoops, innerLoops, runnable); - analyze(stats, mTimes, outerLoops, debugLevel); - innerLoopTime = stats.getMedianInMicros(); - if ((innerLoopTime >= minThresholdInMicros) - && (innerLoopTime <= maxThresholdInMicros)) { - if (stats.stdDevOk(maxStdDevRatio)) { - successful = true; - break; - } else { - stats.incStdDevTooLargeCount(); - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format( - "tea: tlc=%d StdDevRatio=%.2f > maxStdDevRatio=%.2f", - stats.getStdDevTooLargeCount(), stats.getStdDevRatio(), - maxStdDevRatio)); - } - } - } else if (binarySearch) { - if ((innerLoopTime < minThresholdInMicros)) { - minInnerLoops = innerLoops; - } else { - maxInnerLoops = innerLoops; - } - innerLoops = (maxInnerLoops + minInnerLoops) / 2; - } else if (innerLoopTime >= maxThresholdInMicros) { - /* Found a too large value, change to binary search */ - binarySearch = true; - maxInnerLoops = innerLoops; - innerLoops = (maxInnerLoops + minInnerLoops) / 2; - } else { - innerLoops *= 10; - } - } - if (successful) { - break; - } - } - } - if (!successful) { - /* Couldn't find the number of loops to execute */ - throw new PerfTimerException(); - } - - /** Looking for minimum */ - if ((minStats == null) || (minStats.getTimePerLoop() > stats.getTimePerLoop())) { - minStats = stats; - } - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format("minStats.getTimePerLoop=%f minStats: %s", minStats.getTimePerLoop(), minStats)); - } - } - - return minStats; - } - - /** - * Time how long it takes to execute runnable.run() with a threshold of 1 to - * 10ms. - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @param runnable - * @throws PerfTimerException - */ - public Stats timeEachAutomatically(int debugLevel, Runnable runnable) - throws PerfTimerException { - mStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, 1, mCr.mMinThresholdInMicros, - mCr.mMaxThresholdInMicros, mCr.mStdDevRetrys, mCr.mMaxStdDevRatio, debugLevel, - runnable); - return mStats; - } - - /** - * Time how long it takes to execute runnable.run() with a threshold of 1 to - * 10ms. - * - * @param runnable - * @throws PerfTimerException - */ - public Stats timeEachAutomatically(Runnable runnable) throws PerfTimerException { - mStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, 1, mCr.mMinThresholdInMicros, - mCr.mMaxThresholdInMicros, mCr.mStdDevRetrys, mCr.mMaxStdDevRatio, - DEBUG_LEVEL_NONE, runnable); - return mStats; - } - - /** Resize the times array */ - public void resize(int maxCount) { - if (maxCount > mTimes.length) { - mTimes = new long[maxCount]; - } - } - - /** - * Analyze the data calculating the min, max, total, median, mean and - * stdDev. The standard deviation is calculated as sqrt(((sum of the squares - * of each time) / count) - mean^2) - * {@link "http://www.sciencebuddies.org/mentoring/project_data_analysis_variance_std_deviation.shtml"} - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @return StopWatch - */ - public Stats analyze(Stats stats, long data[], int count, int debugLevel) { - if (count > 0) { - if (debugLevel >= DEBUG_LEVEL_ALL) { - for (int j = 0; j < count; j++) { - log(String.format("data[%d]=%,dns", j, data[j])); - } - } - stats.calculate(data, count); - } else { - stats.init(); - } - if (debugLevel >= DEBUG_LEVEL_SOME) { - log("stats: " + stats); - } - return stats; - } - - /** - * Calibrate the system and set it for this PerfTimer instance - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @param precisionInDecimalDigits the precision in number of decimal digits - */ - public CalibrationRec calibrate(int debugLevel, double precisionInDecimalDigits) - throws PerfTimerException { - int nonZeroCount = 0; - Stats stats = new Stats(); - CalibrationRec cr = new CalibrationRec(); - - /* initialize the precision */ - cr.mPrecisionInDecimalDigits = precisionInDecimalDigits; - - /* Warm up the cache */ - timeEach(stats, OUTER_LOOPS, 10, mEmptyRunnable); - - /* - * Determine the clock stats with at least 20% non-zero unique values. - */ - for (int clockStatsTries = 1; clockStatsTries < 100; clockStatsTries++) { - int j; - int i; - long cur; - long prev; - long min; - - int innerLoops = clockStatsTries * 10; - timeEach(stats, OUTER_LOOPS, innerLoops, mEmptyRunnable); - long nonZeroValues[] = new long[mCount]; - prev = 0; - for (nonZeroCount = 0, i = 0; i < mCount; i++) { - cur = mTimes[i]; - if (cur > 0) { - nonZeroValues[nonZeroCount++] = cur; - } - } - if (nonZeroCount > (mCount * 0.20)) { - // Calculate thresholds - analyze(stats, nonZeroValues, nonZeroCount, debugLevel); - stats.calculate(nonZeroValues, nonZeroCount); - cr.mMinThresholdInMicros = stats.getMeanInMicros() - * Math.pow(10, cr.mPrecisionInDecimalDigits); - cr.mMaxThresholdInMicros = cr.mMinThresholdInMicros * 2; - - // Set overhead to 0 and time the empty loop then set overhead. - cr.mRunnableOverheadInMicros = 0; - mClockStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, innerLoops, - cr.mMinThresholdInMicros, cr.mMaxThresholdInMicros, mCr.mStdDevRetrys, - mCr.mMaxStdDevRatio, debugLevel, mEmptyRunnable); - cr.mRunnableOverheadInMicros = mClockStats.getMinInMicros() - / mClockStats.getInnerLoops(); - break; - } - nonZeroCount = 0; - } - if (nonZeroCount == 0) { - throw new PerfTimerException(); - } - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format("calibrate X oh=%.6fus minT=%,.6fus maxT=%,.6fus stats: %s", - cr.mRunnableOverheadInMicros, cr.mMinThresholdInMicros, - cr.mMaxThresholdInMicros, stats)); - } - mCr = cr; - return mCr; - } - - /** Calibrate the system and set it for this PerfTimer instance */ - public CalibrationRec calibrate(double precisionInDecimalDigits) throws PerfTimerException { - return calibrate(DEBUG_LEVEL_NONE, precisionInDecimalDigits); - } - - /** Calibrate the system and set it for this PerfTimer instance */ - public CalibrationRec calibrate() throws PerfTimerException { - return calibrate(DEBUG_LEVEL_NONE, mCr.mPrecisionInDecimalDigits); - } - - /* - * Accessors for the private data - */ - - /** Set calibration record */ - public void setCalibrationRec(CalibrationRec cr) { - mCr = cr; - } - - /** Get calibration record */ - public CalibrationRec getCalibrationRec() { - return mCr; - } - - /** Number of samples in times array. */ - public int getCount() { - return mCount; - } - - /** Minimum value of collected data in microseconds, valid after analyze. */ - public double getMinInMicros() { - return mStats.getMinInMicros(); - } - - /** Maximum value of collected data in microseconds, valid after analyze. */ - public double getMaxInMicros() { - return mStats.getMaxInMicros(); - } - - /** - * Sum of the values of collected data in microseconds, valid after analyze. - */ - public double getTotalInMicros() { - return mStats.getTotalInMicros(); - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getTotalInSecs() { - return mStats.getTotalInSecs(); - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getMeanInMicros() { - return mStats.getMeanInMicros(); - } - - /** Median value of collected data in microseconds, valid after analyze. */ - public double getMedianInMicros() { - return mStats.getMedianInMicros(); - } - - /** - * Standard deviation of collected data in microseconds, valid after - * analyze. - */ - public double getStdDevInMicros() { - return mStats.getStdDevInMicros(); - } - - /** The mTimes[index] value */ - public long getTime(int index) { - return mTimes[index]; - } - - /** The mTimes */ - public long[] getTimes() { - return mTimes; - } - - /** @return the clock stats as measured in calibrate */ - public Stats getClockStats() { - return mClockStats; - } - - /** @return the stats */ - public Stats getStats() { - return mStats; - } - - /** - * Convert stats to string - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - */ - public String stats(int debugLevel) { - int innerLoops = mStats.getInnerLoops(); - if (mCount == 0) { - return String.format("%,.3fus", (getTicks() - mStart) / TICKS_PER_MICROSECOND); - } else { - if (mCount == 1) { - return String.format("%,.3fus", getTime()); - } else { - analyze(mStats, mTimes, mCount, debugLevel); - return mStats.toString(); - } - } - } - - /** - * Convert string - */ - public String stats() { - return stats(0); - } - - /** - * Get time - */ - public double getTime() { - int innerLoops = mStats.getInnerLoops(); - if (mCount == 0) { - return (getTicks() - mStart) / TICKS_PER_MICROSECOND; - } else { - if (mCount == 1) { - return mStats.getTotalInMicros(); - } else { - analyze(mStats, mTimes, mCount, DEBUG_LEVEL_NONE); - return (mStats.getMinInMicros() / innerLoops) - mCr.mRunnableOverheadInMicros; - } - } - } - - /** Convert to string */ - @Override - public String toString() { - return String.format("%,.3fus", getTime()); - } -} diff --git a/java/src/test/java/com/google/protobuf/ServiceTest.java b/java/src/test/java/com/google/protobuf/ServiceTest.java index d8523ea..e10322d 100644 --- a/java/src/test/java/com/google/protobuf/ServiceTest.java +++ b/java/src/test/java/com/google/protobuf/ServiceTest.java @@ -30,7 +30,9 @@ package com.google.protobuf; +import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; +import google.protobuf.no_generic_services_test.UnittestNoGenericServices; import protobuf_unittest.MessageWithNoOuter; import protobuf_unittest.ServiceWithNoOuter; import protobuf_unittest.UnittestProto.TestAllTypes; @@ -44,6 +46,9 @@ import org.easymock.classextension.EasyMock; import org.easymock.classextension.IMocksControl; import org.easymock.IArgumentMatcher; +import java.util.HashSet; +import java.util.Set; + import junit.framework.TestCase; /** @@ -220,6 +225,48 @@ public class ServiceTest extends TestCase { control.verify(); } + public void testNoGenericServices() throws Exception { + // Non-services should be usable. + UnittestNoGenericServices.TestMessage message = + UnittestNoGenericServices.TestMessage.newBuilder() + .setA(123) + .setExtension(UnittestNoGenericServices.testExtension, 456) + .build(); + assertEquals(123, message.getA()); + assertEquals(1, UnittestNoGenericServices.TestEnum.FOO.getNumber()); + + // Build a list of the class names nested in UnittestNoGenericServices. + String outerName = "google.protobuf.no_generic_services_test." + + "UnittestNoGenericServices"; + Class<?> outerClass = Class.forName(outerName); + + Set<String> innerClassNames = new HashSet<String>(); + for (Class<?> innerClass : outerClass.getClasses()) { + String fullName = innerClass.getName(); + // Figure out the unqualified name of the inner class. + // Note: Surprisingly, the full name of an inner class will be separated + // from the outer class name by a '$' rather than a '.'. This is not + // mentioned in the documentation for java.lang.Class. I don't want to + // make assumptions, so I'm just going to accept any character as the + // separator. + assertTrue(fullName.startsWith(outerName)); + innerClassNames.add(fullName.substring(outerName.length() + 1)); + } + + // No service class should have been generated. + assertTrue(innerClassNames.contains("TestMessage")); + assertTrue(innerClassNames.contains("TestEnum")); + assertFalse(innerClassNames.contains("TestService")); + + // But descriptors are there. + FileDescriptor file = UnittestNoGenericServices.getDescriptor(); + assertEquals(1, file.getServices().size()); + assertEquals("TestService", file.getServices().get(0).getName()); + assertEquals(1, file.getServices().get(0).getMethods().size()); + assertEquals("Foo", + file.getServices().get(0).getMethods().get(0).getName()); + } + // ================================================================= /** diff --git a/java/src/test/java/com/google/protobuf/TestUtil.java b/java/src/test/java/com/google/protobuf/TestUtil.java index 805c42a..2b8b2af 100644 --- a/java/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/src/test/java/com/google/protobuf/TestUtil.java @@ -217,6 +217,7 @@ import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestPackedExtensions; import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; import protobuf_unittest.UnittestProto.ForeignMessage; import protobuf_unittest.UnittestProto.ForeignEnum; import com.google.protobuf.test.UnittestImport.ImportMessage; @@ -289,6 +290,12 @@ class TestUtil { return builder.build(); } + public static TestUnpackedTypes getUnpackedSet() { + TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); + setUnpackedFields(builder); + return builder.build(); + } + public static TestPackedExtensions getPackedExtensionsSet() { TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder(); setPackedExtensions(builder); @@ -956,6 +963,42 @@ class TestUtil { } /** + * Set every field of {@code message} to a unique value. Must correspond with + * the values applied by {@code setPackedFields}. + */ + public static void setUnpackedFields(TestUnpackedTypes.Builder message) { + message.addUnpackedInt32 (601); + message.addUnpackedInt64 (602); + message.addUnpackedUint32 (603); + message.addUnpackedUint64 (604); + message.addUnpackedSint32 (605); + message.addUnpackedSint64 (606); + message.addUnpackedFixed32 (607); + message.addUnpackedFixed64 (608); + message.addUnpackedSfixed32(609); + message.addUnpackedSfixed64(610); + message.addUnpackedFloat (611); + message.addUnpackedDouble (612); + message.addUnpackedBool (true); + message.addUnpackedEnum (ForeignEnum.FOREIGN_BAR); + // Add a second one of each field. + message.addUnpackedInt32 (701); + message.addUnpackedInt64 (702); + message.addUnpackedUint32 (703); + message.addUnpackedUint64 (704); + message.addUnpackedSint32 (705); + message.addUnpackedSint64 (706); + message.addUnpackedFixed32 (707); + message.addUnpackedFixed64 (708); + message.addUnpackedSfixed32(709); + message.addUnpackedSfixed64(710); + message.addUnpackedFloat (711); + message.addUnpackedDouble (712); + message.addUnpackedBool (false); + message.addUnpackedEnum (ForeignEnum.FOREIGN_BAZ); + } + + /** * Assert (using {@code junit.framework.Assert}} that all fields of * {@code message} are set to the values assigned by {@code setPackedFields}. */ @@ -1004,6 +1047,55 @@ class TestUtil { Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1)); } + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are set to the values assigned by {@code setUnpackedFields}. + */ + public static void assertUnpackedFieldsSet(TestUnpackedTypes message) { + Assert.assertEquals(2, message.getUnpackedInt32Count ()); + Assert.assertEquals(2, message.getUnpackedInt64Count ()); + Assert.assertEquals(2, message.getUnpackedUint32Count ()); + Assert.assertEquals(2, message.getUnpackedUint64Count ()); + Assert.assertEquals(2, message.getUnpackedSint32Count ()); + Assert.assertEquals(2, message.getUnpackedSint64Count ()); + Assert.assertEquals(2, message.getUnpackedFixed32Count ()); + Assert.assertEquals(2, message.getUnpackedFixed64Count ()); + Assert.assertEquals(2, message.getUnpackedSfixed32Count()); + Assert.assertEquals(2, message.getUnpackedSfixed64Count()); + Assert.assertEquals(2, message.getUnpackedFloatCount ()); + Assert.assertEquals(2, message.getUnpackedDoubleCount ()); + Assert.assertEquals(2, message.getUnpackedBoolCount ()); + Assert.assertEquals(2, message.getUnpackedEnumCount ()); + Assert.assertEquals(601 , message.getUnpackedInt32 (0)); + Assert.assertEquals(602 , message.getUnpackedInt64 (0)); + Assert.assertEquals(603 , message.getUnpackedUint32 (0)); + Assert.assertEquals(604 , message.getUnpackedUint64 (0)); + Assert.assertEquals(605 , message.getUnpackedSint32 (0)); + Assert.assertEquals(606 , message.getUnpackedSint64 (0)); + Assert.assertEquals(607 , message.getUnpackedFixed32 (0)); + Assert.assertEquals(608 , message.getUnpackedFixed64 (0)); + Assert.assertEquals(609 , message.getUnpackedSfixed32(0)); + Assert.assertEquals(610 , message.getUnpackedSfixed64(0)); + Assert.assertEquals(611 , message.getUnpackedFloat (0), 0.0); + Assert.assertEquals(612 , message.getUnpackedDouble (0), 0.0); + Assert.assertEquals(true , message.getUnpackedBool (0)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getUnpackedEnum(0)); + Assert.assertEquals(701 , message.getUnpackedInt32 (1)); + Assert.assertEquals(702 , message.getUnpackedInt64 (1)); + Assert.assertEquals(703 , message.getUnpackedUint32 (1)); + Assert.assertEquals(704 , message.getUnpackedUint64 (1)); + Assert.assertEquals(705 , message.getUnpackedSint32 (1)); + Assert.assertEquals(706 , message.getUnpackedSint64 (1)); + Assert.assertEquals(707 , message.getUnpackedFixed32 (1)); + Assert.assertEquals(708 , message.getUnpackedFixed64 (1)); + Assert.assertEquals(709 , message.getUnpackedSfixed32(1)); + Assert.assertEquals(710 , message.getUnpackedSfixed64(1)); + Assert.assertEquals(711 , message.getUnpackedFloat (1), 0.0); + Assert.assertEquals(712 , message.getUnpackedDouble (1), 0.0); + Assert.assertEquals(false, message.getUnpackedBool (1)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getUnpackedEnum(1)); + } + // =================================================================== // Like above, but for extensions @@ -1572,6 +1664,34 @@ class TestUtil { Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension)); Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension)); + // Repeated fields are empty via getExtension().size(). + Assert.assertEquals(0, message.getExtension(repeatedInt32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedInt64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedUint32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedUint64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSint32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSint64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedFixed32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedFixed64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSfixed32Extension).size()); + Assert.assertEquals(0, message.getExtension(repeatedSfixed64Extension).size()); + Assert.assertEquals(0, message.getExtension(repeatedFloatExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedDoubleExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedBoolExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedStringExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedBytesExtension ).size()); + + Assert.assertEquals(0, message.getExtension(repeatedGroupExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedNestedMessageExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedForeignMessageExtension).size()); + Assert.assertEquals(0, message.getExtension(repeatedImportMessageExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedNestedEnumExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedForeignEnumExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedImportEnumExtension ).size()); + + Assert.assertEquals(0, message.getExtension(repeatedStringPieceExtension).size()); + Assert.assertEquals(0, message.getExtension(repeatedCordExtension).size()); + // hasBlah() should also be false for all default fields. Assert.assertFalse(message.hasExtension(defaultInt32Extension )); Assert.assertFalse(message.hasExtension(defaultInt64Extension )); diff --git a/java/src/test/java/com/google/protobuf/TextFormatTest.java b/java/src/test/java/com/google/protobuf/TextFormatTest.java index 1d73165..60bd800 100644 --- a/java/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/src/test/java/com/google/protobuf/TextFormatTest.java @@ -68,7 +68,7 @@ public class TextFormatTest extends TestCase { private static String allExtensionsSetText = TestUtil.readTextFromFile( "text_format_unittest_extensions_data.txt"); - private String exoticText = + private static String exoticText = "repeated_int32: -1\n" + "repeated_int32: -2147483648\n" + "repeated_int64: -1\n" + @@ -80,7 +80,13 @@ public class TextFormatTest extends TestCase { "repeated_double: 123.0\n" + "repeated_double: 123.5\n" + "repeated_double: 0.125\n" + + "repeated_double: .125\n" + + "repeated_double: -.125\n" + "repeated_double: 1.23E17\n" + + "repeated_double: 1.23E+17\n" + + "repeated_double: -1.23e-17\n" + + "repeated_double: .23e+17\n" + + "repeated_double: -.23E17\n" + "repeated_double: 1.235E22\n" + "repeated_double: 1.235E-18\n" + "repeated_double: 123.456789\n" + @@ -91,6 +97,10 @@ public class TextFormatTest extends TestCase { "\\341\\210\\264\"\n" + "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n"; + private static String canonicalExoticText = + exoticText.replace(": .", ": 0.").replace(": -.", ": -0.") // short-form double + .replace("23e", "23E").replace("E+", "E").replace("0.23E17", "2.3E16"); + private String messageSetText = "[protobuf_unittest.TestMessageSetExtension1] {\n" + " i: 123\n" + @@ -186,12 +196,12 @@ public class TextFormatTest extends TestCase { final FieldDescriptor optionalField = TestAllTypes.getDescriptor().findFieldByName("optional_nested_message"); final Object value = NestedMessage.newBuilder().setBb(42).build(); - + assertEquals( "optional_nested_message {\n bb: 42\n}\n", TextFormat.printFieldToString(optionalField, value)); } - + /** * Helper to construct a ByteString from a String containing only 8-bit * characters. The characters are converted directly to bytes, *not* @@ -231,7 +241,13 @@ public class TextFormatTest extends TestCase { .addRepeatedDouble(123) .addRepeatedDouble(123.5) .addRepeatedDouble(0.125) + .addRepeatedDouble(.125) + .addRepeatedDouble(-.125) + .addRepeatedDouble(123e15) .addRepeatedDouble(123e15) + .addRepeatedDouble(-1.23e-17) + .addRepeatedDouble(.23e17) + .addRepeatedDouble(-23e15) .addRepeatedDouble(123.5e20) .addRepeatedDouble(123.5e-20) .addRepeatedDouble(123.456789) @@ -244,7 +260,7 @@ public class TextFormatTest extends TestCase { .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe")) .build(); - assertEquals(exoticText, message.toString()); + assertEquals(canonicalExoticText, message.toString()); } public void testPrintMessageSet() throws Exception { @@ -319,7 +335,7 @@ public class TextFormatTest extends TestCase { // Too lazy to check things individually. Don't try to debug this // if testPrintExotic() is failing. - assertEquals(exoticText, builder.build().toString()); + assertEquals(canonicalExoticText, builder.build().toString()); } public void testParseMessageSet() throws Exception { @@ -633,4 +649,10 @@ public class TextFormatTest extends TestCase { TextFormat.merge("optional_string: \"" + longText + "\"", builder); assertEquals(longText, builder.getOptionalString()); } + + public void testParseAdjacentStringLiterals() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder); + assertEquals("foocorgegrault", builder.getOptionalString()); + } } diff --git a/java/src/test/java/com/google/protobuf/WireFormatTest.java b/java/src/test/java/com/google/protobuf/WireFormatTest.java index bd1c6db..5ea1dd6 100644 --- a/java/src/test/java/com/google/protobuf/WireFormatTest.java +++ b/java/src/test/java/com/google/protobuf/WireFormatTest.java @@ -102,6 +102,28 @@ public class WireFormatTest extends TestCase { assertEquals(rawBytes, rawBytes2); } + public void testSerializationPackedWithoutGetSerializedSize() + throws Exception { + // Write directly to an OutputStream, without invoking getSerializedSize() + // This used to be a bug where the size of a packed field was incorrect, + // since getSerializedSize() was never invoked. + TestPackedTypes message = TestUtil.getPackedSet(); + + // Directly construct a CodedOutputStream around the actual OutputStream, + // in case writeTo(OutputStream output) invokes getSerializedSize(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream); + + message.writeTo(codedOutput); + + codedOutput.flush(); + + TestPackedTypes message2 = TestPackedTypes.parseFrom( + outputStream.toByteArray()); + + TestUtil.assertPackedFieldsSet(message2); + } + public void testSerializeExtensionsLite() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllExtensions then parse it as TestAllTypes @@ -213,6 +235,9 @@ public class WireFormatTest extends TestCase { TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input)); assertEquals(34, input.read()); assertEquals(-1, input.read()); + + // We're at EOF, so parsing again should return null. + assertTrue(TestAllTypes.parseDelimitedFrom(input) == null); } private void assertFieldsInOrder(ByteString data) throws Exception { diff --git a/m4/acx_check_suncc.m4 b/m4/acx_check_suncc.m4 index 3464a84..4e8f961 100644 --- a/m4/acx_check_suncc.m4 +++ b/m4/acx_check_suncc.m4 @@ -26,7 +26,7 @@ AC_DEFUN([ACX_CHECK_SUNCC],[ AS_IF([test "$SUNCC" = "yes" -a "x${ac_cv_env_CXXFLAGS_set}" = "x"],[ dnl Sun Studio has a crashing bug with -xO4 in some cases. Keep this dnl at -xO3 until a proper test to detect those crashes can be done. - CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -template=no%extdef ${CXXFLAGS}" + CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -library=Crun -template=no%extdef ${CXXFLAGS}" ]) case $host_os in @@ -42,10 +42,6 @@ AC_DEFUN([ACX_CHECK_SUNCC],[ AS_IF([test "x$ac_enable_64bit" = "xyes"],[ - AS_IF([test "x${ac_cv_env_LDFLAGS_set}" = "x"],[ - LDFLAGS="-L/usr/local/lib/${isainfo_k} ${LDFLAGS}" - ]) - AS_IF([test "x$libdir" = "x\${exec_prefix}/lib"],[ dnl The user hasn't overridden the default libdir, so we'll dnl the dir suffix to match solaris 32/64-bit policy @@ -54,12 +50,19 @@ AC_DEFUN([ACX_CHECK_SUNCC],[ dnl This should just be set in CPPFLAGS and in LDFLAGS, but libtool dnl does the wrong thing if you don't put it into CXXFLAGS. sigh. + dnl (It also needs it in CFLAGS, or it does a different wrong thing!) AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[ CXXFLAGS="${CXXFLAGS} -m64" ac_cv_env_CXXFLAGS_set=set ac_cv_env_CXXFLAGS_value='-m64' ]) + AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"],[ + CFLAGS="${CFLAGS} -m64" + ac_cv_env_CFLAGS_set=set + ac_cv_env_CFLAGS_value='-m64' + ]) + AS_IF([test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes" ],[ CXXFLAGS="-xmemalign=8s ${CXXFLAGS}" ]) diff --git a/m4/stl_hash.m4 b/m4/stl_hash.m4 index 912b954..08813c9 100644 --- a/m4/stl_hash.m4 +++ b/m4/stl_hash.m4 @@ -14,28 +14,45 @@ AC_DEFUN([AC_CXX_STL_HASH], [AC_MSG_CHECKING(the location of hash_map) AC_LANG_SAVE AC_LANG_CPLUSPLUS - ac_cv_cxx_hash_map="" - for location in ext/hash_map hash_map; do - for namespace in __gnu_cxx "" std stdext; do - if test -z "$ac_cv_cxx_hash_map"; then - AC_TRY_COMPILE([#include <$location>], - [${namespace}::hash_map<int, int> t], - [ac_cv_cxx_hash_map="<$location>"; - ac_cv_cxx_hash_namespace="$namespace";]) - fi + ac_cv_cxx_hash_map_header="" + ac_cv_cxx_hash_map_class="" + for location in [tr1/unordered_map ext/hash_map hash_map]; do + for namespace in [std::tr1 __gnu_cxx "" std stdext]; do + for name in [unordered_map hash_map]; do + + if test -z "$ac_cv_cxx_hash_map_header"; then + + # On OSX 1.5 / GCC 4.0.1 (the standard compiler on that platform), + # calling find() on a const unordered_map does not compile. So, we + # include a call to find() in our test to detect this broken + # implementation and avoid using it. Note that ext/hash_map works + # fine on this platform, so we'll end up using that. + AC_TRY_COMPILE([#include <$location>], + [const ${namespace}::$name<int, int> t; + t.find(1);], + [ac_cv_cxx_hash_map_header="<$location>"; + ac_cv_cxx_hash_namespace="$namespace"; + ac_cv_cxx_hash_map_class="$name";]) + fi + done done done - ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`; - if test -n "$ac_cv_cxx_hash_map"; then + ac_cv_cxx_hash_set_header=`echo "$ac_cv_cxx_hash_map_header" | sed s/map/set/`; + ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`; + if test -n "$ac_cv_cxx_hash_map_header"; then AC_DEFINE(HAVE_HASH_MAP, 1, [define if the compiler has hash_map]) AC_DEFINE(HAVE_HASH_SET, 1, [define if the compiler has hash_set]) - AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map, + AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map_header, [the location of <hash_map>]) - AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set, + AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set_header, [the location of <hash_set>]) + AC_DEFINE_UNQUOTED(HASH_MAP_CLASS,$ac_cv_cxx_hash_map_class, + [the name of <hash_set>]) + AC_DEFINE_UNQUOTED(HASH_SET_CLASS,$ac_cv_cxx_hash_set_class, + [the name of <hash_set>]) AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace, [the namespace of hash_map/hash_set]) - AC_MSG_RESULT([$ac_cv_cxx_hash_map]) + AC_MSG_RESULT([$ac_cv_cxx_hash_map_header]) else AC_MSG_RESULT() AC_MSG_WARN([could not find an STL hash_map]) diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index 8e3fc2e..aa4ab96 100755 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -44,12 +44,24 @@ file, in types that make this information accessible in Python. __author__ = 'robinson@google.com (Will Robinson)' + +class Error(Exception): + """Base error for this module.""" + + class DescriptorBase(object): """Descriptors base class. This class is the base of all descriptor classes. It provides common options related functionaility. + + Attributes: + has_options: True if the descriptor has non-default options. Usually it + is not necessary to read this -- just call GetOptions() which will + happily return the default instance. However, it's sometimes useful + for efficiency, and also useful inside the protobuf implementation to + avoid some bootstrapping issues. """ def __init__(self, options, options_class_name): @@ -60,6 +72,9 @@ class DescriptorBase(object): self._options = options self._options_class_name = options_class_name + # Does this descriptor have non-default options? + self.has_options = options is not None + def GetOptions(self): """Retrieves descriptor options. @@ -78,7 +93,70 @@ class DescriptorBase(object): return self._options -class Descriptor(DescriptorBase): +class _NestedDescriptorBase(DescriptorBase): + """Common class for descriptors that can be nested.""" + + def __init__(self, options, options_class_name, name, full_name, + file, containing_type, serialized_start=None, + serialized_end=None): + """Constructor. + + Args: + options: Protocol message options or None + to use default message options. + options_class_name: (str) The class name of the above options. + + name: (str) Name of this protocol message type. + full_name: (str) Fully-qualified name of this protocol message type, + which will include protocol "package" name and the name of any + enclosing types. + file: (FileDescriptor) Reference to file info. + containing_type: if provided, this is a nested descriptor, with this + descriptor as parent, otherwise None. + serialized_start: The start index (inclusive) in block in the + file.serialized_pb that describes this descriptor. + serialized_end: The end index (exclusive) in block in the + file.serialized_pb that describes this descriptor. + """ + super(_NestedDescriptorBase, self).__init__( + options, options_class_name) + + self.name = name + # TODO(falk): Add function to calculate full_name instead of having it in + # memory? + self.full_name = full_name + self.file = file + self.containing_type = containing_type + + self._serialized_start = serialized_start + self._serialized_end = serialized_end + + def GetTopLevelContainingType(self): + """Returns the root if this is a nested type, or itself if its the root.""" + desc = self + while desc.containing_type is not None: + desc = desc.containing_type + return desc + + def CopyToProto(self, proto): + """Copies this to the matching proto in descriptor_pb2. + + Args: + proto: An empty proto instance from descriptor_pb2. + + Raises: + Error: If self couldnt be serialized, due to to few constructor arguments. + """ + if (self.file is not None and + self._serialized_start is not None and + self._serialized_end is not None): + proto.ParseFromString(self.file.serialized_pb[ + self._serialized_start:self._serialized_end]) + else: + raise Error('Descriptor does not contain serialization.') + + +class Descriptor(_NestedDescriptorBase): """Descriptor for a protocol message type. @@ -89,10 +167,8 @@ class Descriptor(DescriptorBase): which will include protocol "package" name and the name of any enclosing types. - filename: (str) Name of the .proto file containing this message. - containing_type: (Descriptor) Reference to the descriptor of the - type containing us, or None if we have no containing type. + type containing us, or None if this is top-level. fields: (list of FieldDescriptors) Field descriptors for all fields in this type. @@ -123,20 +199,28 @@ class Descriptor(DescriptorBase): objects as |extensions|, but indexed by "name" attribute of each FieldDescriptor. + is_extendable: Does this type define any extension ranges? + options: (descriptor_pb2.MessageOptions) Protocol message options or None to use default message options. + + file: (FileDescriptor) Reference to file descriptor. """ - def __init__(self, name, full_name, filename, containing_type, - fields, nested_types, enum_types, extensions, options=None): + def __init__(self, name, full_name, filename, containing_type, fields, + nested_types, enum_types, extensions, options=None, + is_extendable=True, extension_ranges=None, file=None, + serialized_start=None, serialized_end=None): """Arguments to __init__() are as described in the description of Descriptor fields above. + + Note that filename is an obsolete argument, that is not used anymore. + Please use file.name to access this as an attribute. """ - super(Descriptor, self).__init__(options, 'MessageOptions') - self.name = name - self.full_name = full_name - self.filename = filename - self.containing_type = containing_type + super(Descriptor, self).__init__( + options, 'MessageOptions', name, full_name, file, + containing_type, serialized_start=serialized_start, + serialized_end=serialized_start) # We have fields in addition to fields_by_name and fields_by_number, # so that: @@ -163,6 +247,20 @@ class Descriptor(DescriptorBase): for extension in self.extensions: extension.extension_scope = self self.extensions_by_name = dict((f.name, f) for f in extensions) + self.is_extendable = is_extendable + self.extension_ranges = extension_ranges + + self._serialized_start = serialized_start + self._serialized_end = serialized_end + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.DescriptorProto. + + Args: + proto: An empty descriptor_pb2.DescriptorProto. + """ + # This function is overriden to give a better doc comment. + super(Descriptor, self).CopyToProto(proto) # TODO(robinson): We should have aggressive checking here, @@ -195,6 +293,8 @@ class FieldDescriptor(DescriptorBase): label: (One of the LABEL_* constants below) Tells whether this field is optional, required, or repeated. + has_default_value: (bool) True if this field has a default value defined, + otherwise false. default_value: (Varies) Default value of this field. Only meaningful for non-repeated scalar fields. Repeated fields should always set this to [], and non-repeated composite @@ -272,7 +372,8 @@ class FieldDescriptor(DescriptorBase): def __init__(self, name, full_name, index, number, type, cpp_type, label, default_value, message_type, enum_type, containing_type, - is_extension, extension_scope, options=None): + is_extension, extension_scope, options=None, + has_default_value=True): """The arguments are as described in the description of FieldDescriptor attributes above. @@ -288,6 +389,7 @@ class FieldDescriptor(DescriptorBase): self.type = type self.cpp_type = cpp_type self.label = label + self.has_default_value = has_default_value self.default_value = default_value self.containing_type = containing_type self.message_type = message_type @@ -296,7 +398,7 @@ class FieldDescriptor(DescriptorBase): self.extension_scope = extension_scope -class EnumDescriptor(DescriptorBase): +class EnumDescriptor(_NestedDescriptorBase): """Descriptor for an enum defined in a .proto file. @@ -305,7 +407,6 @@ class EnumDescriptor(DescriptorBase): name: (str) Name of the enum type. full_name: (str) Full name of the type, including package name and any enclosing type(s). - filename: (str) Name of the .proto file in which this appears. values: (list of EnumValueDescriptors) List of the values in this enum. @@ -317,23 +418,41 @@ class EnumDescriptor(DescriptorBase): type of this enum, or None if this is an enum defined at the top level in a .proto file. Set by Descriptor's constructor if we're passed into one. + file: (FileDescriptor) Reference to file descriptor. options: (descriptor_pb2.EnumOptions) Enum options message or None to use default enum options. """ def __init__(self, name, full_name, filename, values, - containing_type=None, options=None): - """Arguments are as described in the attribute description above.""" - super(EnumDescriptor, self).__init__(options, 'EnumOptions') - self.name = name - self.full_name = full_name - self.filename = filename + containing_type=None, options=None, file=None, + serialized_start=None, serialized_end=None): + """Arguments are as described in the attribute description above. + + Note that filename is an obsolete argument, that is not used anymore. + Please use file.name to access this as an attribute. + """ + super(EnumDescriptor, self).__init__( + options, 'EnumOptions', name, full_name, file, + containing_type, serialized_start=serialized_start, + serialized_end=serialized_start) + self.values = values for value in self.values: value.type = self self.values_by_name = dict((v.name, v) for v in values) self.values_by_number = dict((v.number, v) for v in values) - self.containing_type = containing_type + + self._serialized_start = serialized_start + self._serialized_end = serialized_end + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.EnumDescriptorProto. + + Args: + proto: An empty descriptor_pb2.EnumDescriptorProto. + """ + # This function is overriden to give a better doc comment. + super(EnumDescriptor, self).CopyToProto(proto) class EnumValueDescriptor(DescriptorBase): @@ -360,7 +479,7 @@ class EnumValueDescriptor(DescriptorBase): self.type = type -class ServiceDescriptor(DescriptorBase): +class ServiceDescriptor(_NestedDescriptorBase): """Descriptor for a service. @@ -372,12 +491,15 @@ class ServiceDescriptor(DescriptorBase): service. options: (descriptor_pb2.ServiceOptions) Service options message or None to use default service options. + file: (FileDescriptor) Reference to file info. """ - def __init__(self, name, full_name, index, methods, options=None): - super(ServiceDescriptor, self).__init__(options, 'ServiceOptions') - self.name = name - self.full_name = full_name + def __init__(self, name, full_name, index, methods, options=None, file=None, + serialized_start=None, serialized_end=None): + super(ServiceDescriptor, self).__init__( + options, 'ServiceOptions', name, full_name, file, + None, serialized_start=serialized_start, + serialized_end=serialized_end) self.index = index self.methods = methods # Set the containing service for each method in this service. @@ -391,6 +513,15 @@ class ServiceDescriptor(DescriptorBase): return method return None + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.ServiceDescriptorProto. + + Args: + proto: An empty descriptor_pb2.ServiceDescriptorProto. + """ + # This function is overriden to give a better doc comment. + super(ServiceDescriptor, self).CopyToProto(proto) + class MethodDescriptor(DescriptorBase): @@ -423,6 +554,32 @@ class MethodDescriptor(DescriptorBase): self.output_type = output_type +class FileDescriptor(DescriptorBase): + """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. + + name: name of file, relative to root of source tree. + package: name of the package + serialized_pb: (str) Byte string of serialized + descriptor_pb2.FileDescriptorProto. + """ + + def __init__(self, name, package, options=None, serialized_pb=None): + """Constructor.""" + super(FileDescriptor, self).__init__(options, 'FileOptions') + + self.name = name + self.package = package + self.serialized_pb = serialized_pb + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.FileDescriptorProto. + + Args: + proto: An empty descriptor_pb2.FileDescriptorProto. + """ + proto.ParseFromString(self.serialized_pb) + + def _ParseOptions(message, string): """Parses serialized options. @@ -430,4 +587,4 @@ def _ParseOptions(message, string): proto2 files. It must not be used outside proto2. """ message.ParseFromString(string) - return message; + return message diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py index d8a825d..5cc7d6d 100755 --- a/python/google/protobuf/internal/containers.py +++ b/python/google/protobuf/internal/containers.py @@ -54,8 +54,7 @@ class BaseContainer(object): Args: message_listener: A MessageListener implementation. The RepeatedScalarFieldContainer will call this object's - TransitionToNonempty() method when it transitions from being empty to - being nonempty. + Modified() method when it is modified. """ self._message_listener = message_listener self._values = [] @@ -73,6 +72,9 @@ class BaseContainer(object): # The concrete classes should define __eq__. return not self == other + def __repr__(self): + return repr(self._values) + class RepeatedScalarFieldContainer(BaseContainer): @@ -86,8 +88,7 @@ class RepeatedScalarFieldContainer(BaseContainer): Args: message_listener: A MessageListener implementation. The RepeatedScalarFieldContainer will call this object's - TransitionToNonempty() method when it transitions from being empty to - being nonempty. + Modified() method when it is modified. type_checker: A type_checkers.ValueChecker instance to run on elements inserted into this container. """ @@ -96,44 +97,47 @@ class RepeatedScalarFieldContainer(BaseContainer): def append(self, value): """Appends an item to the list. Similar to list.append().""" - self.insert(len(self._values), value) + self._type_checker.CheckValue(value) + self._values.append(value) + if not self._message_listener.dirty: + self._message_listener.Modified() def insert(self, key, value): """Inserts the item at the specified position. Similar to list.insert().""" self._type_checker.CheckValue(value) self._values.insert(key, value) - self._message_listener.ByteSizeDirty() - if len(self._values) == 1: - self._message_listener.TransitionToNonempty() + if not self._message_listener.dirty: + self._message_listener.Modified() def extend(self, elem_seq): """Extends by appending the given sequence. Similar to list.extend().""" if not elem_seq: return - orig_empty = len(self._values) == 0 new_values = [] for elem in elem_seq: self._type_checker.CheckValue(elem) new_values.append(elem) self._values.extend(new_values) - self._message_listener.ByteSizeDirty() - if orig_empty: - self._message_listener.TransitionToNonempty() + self._message_listener.Modified() + + def MergeFrom(self, other): + """Appends the contents of another repeated field of the same type to this + one. We do not check the types of the individual fields. + """ + self._values.extend(other._values) + self._message_listener.Modified() def remove(self, elem): """Removes an item from the list. Similar to list.remove().""" self._values.remove(elem) - self._message_listener.ByteSizeDirty() + self._message_listener.Modified() def __setitem__(self, key, value): """Sets the item on the specified position.""" - # No need to call TransitionToNonempty(), since if we're able to - # set the element at this index, we were already nonempty before - # this method was called. - self._message_listener.ByteSizeDirty() self._type_checker.CheckValue(value) self._values[key] = value + self._message_listener.Modified() def __getslice__(self, start, stop): """Retrieves the subset of items from between the specified indices.""" @@ -146,17 +150,17 @@ class RepeatedScalarFieldContainer(BaseContainer): self._type_checker.CheckValue(value) new_values.append(value) self._values[start:stop] = new_values - self._message_listener.ByteSizeDirty() + self._message_listener.Modified() def __delitem__(self, key): """Deletes the item at the specified position.""" del self._values[key] - self._message_listener.ByteSizeDirty() + self._message_listener.Modified() def __delslice__(self, start, stop): """Deletes the subset of items from between the specified indices.""" del self._values[start:stop] - self._message_listener.ByteSizeDirty() + self._message_listener.Modified() def __eq__(self, other): """Compares the current instance with another one.""" @@ -186,8 +190,7 @@ class RepeatedCompositeFieldContainer(BaseContainer): Args: message_listener: A MessageListener implementation. The RepeatedCompositeFieldContainer will call this object's - TransitionToNonempty() method when it transitions from being empty to - being nonempty. + Modified() method when it is modified. message_descriptor: A Descriptor instance describing the protocol type that should be present in this container. We'll use the _concrete_class field of this descriptor when the client calls add(). @@ -199,10 +202,24 @@ class RepeatedCompositeFieldContainer(BaseContainer): new_element = self._message_descriptor._concrete_class() new_element._SetListener(self._message_listener) self._values.append(new_element) - self._message_listener.ByteSizeDirty() - self._message_listener.TransitionToNonempty() + if not self._message_listener.dirty: + self._message_listener.Modified() return new_element + def MergeFrom(self, other): + """Appends the contents of another repeated field of the same type to this + one, copying each individual message. + """ + message_class = self._message_descriptor._concrete_class + listener = self._message_listener + values = self._values + for message in other._values: + new_element = message_class() + new_element._SetListener(listener) + new_element.MergeFrom(message) + values.append(new_element) + listener.Modified() + def __getslice__(self, start, stop): """Retrieves the subset of items from between the specified indices.""" return self._values[start:stop] @@ -210,12 +227,12 @@ class RepeatedCompositeFieldContainer(BaseContainer): def __delitem__(self, key): """Deletes the item at the specified position.""" del self._values[key] - self._message_listener.ByteSizeDirty() + self._message_listener.Modified() def __delslice__(self, start, stop): """Deletes the subset of items from between the specified indices.""" del self._values[start:stop] - self._message_listener.ByteSizeDirty() + self._message_listener.Modified() def __eq__(self, other): """Compares the current instance with another one.""" diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py index 83d6fe0..461a30c 100755 --- a/python/google/protobuf/internal/decoder.py +++ b/python/google/protobuf/internal/decoder.py @@ -28,182 +28,614 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Class for decoding protocol buffer primitives. - -Contains the logic for decoding every logical protocol field type -from one of the 5 physical wire types. +"""Code for decoding protocol buffer primitives. + +This code is very similar to encoder.py -- read the docs for that module first. + +A "decoder" is a function with the signature: + Decode(buffer, pos, end, message, field_dict) +The arguments are: + buffer: The string containing the encoded message. + pos: The current position in the string. + end: The position in the string where the current message ends. May be + less than len(buffer) if we're reading a sub-message. + message: The message object into which we're parsing. + field_dict: message._fields (avoids a hashtable lookup). +The decoder reads the field and stores it into field_dict, returning the new +buffer position. A decoder for a repeated field may proactively decode all of +the elements of that field, if they appear consecutively. + +Note that decoders may throw any of the following: + IndexError: Indicates a truncated message. + struct.error: Unpacking of a fixed-width field failed. + message.DecodeError: Other errors. + +Decoders are expected to raise an exception if they are called with pos > end. +This allows callers to be lax about bounds checking: it's fineto read past +"end" as long as you are sure that someone else will notice and throw an +exception later on. + +Something up the call stack is expected to catch IndexError and struct.error +and convert them to message.DecodeError. + +Decoders are constructed using decoder constructors with the signature: + MakeDecoder(field_number, is_repeated, is_packed, key, new_default) +The arguments are: + field_number: The field number of the field we want to decode. + is_repeated: Is the field a repeated field? (bool) + is_packed: Is the field a packed field? (bool) + key: The key to use when looking up the field within field_dict. + (This is actually the FieldDescriptor but nothing in this + file should depend on that.) + new_default: A function which takes a message object as a parameter and + returns a new instance of the default value for this field. + (This is called for repeated fields and sub-messages, when an + instance does not already exist.) + +As with encoders, we define a decoder constructor for every type of field. +Then, for every field of every message class we construct an actual decoder. +That decoder goes into a dict indexed by tag, so when we decode a message +we repeatedly read a tag, look up the corresponding decoder, and invoke it. """ -__author__ = 'robinson@google.com (Will Robinson)' +__author__ = 'kenton@google.com (Kenton Varda)' import struct -from google.protobuf import message -from google.protobuf.internal import input_stream +from google.protobuf.internal import encoder from google.protobuf.internal import wire_format +from google.protobuf import message +# This is not for optimization, but rather to avoid conflicts with local +# variables named "message". +_DecodeError = message.DecodeError + + +def _VarintDecoder(mask): + """Return an encoder for a basic varint value (does not include tag). + + Decoded values will be bitwise-anded with the given mask before being + returned, e.g. to limit them to 32 bits. The returned decoder does not + take the usual "end" parameter -- the caller is expected to do bounds checking + after the fact (often the caller can defer such checking until later). The + decoder returns a (value, new_pos) pair. + """ + + local_ord = ord + def DecodeVarint(buffer, pos): + result = 0 + shift = 0 + while 1: + b = local_ord(buffer[pos]) + result |= ((b & 0x7f) << shift) + pos += 1 + if not (b & 0x80): + result &= mask + return (result, pos) + shift += 7 + if shift >= 64: + raise _DecodeError('Too many bytes when decoding varint.') + return DecodeVarint + + +def _SignedVarintDecoder(mask): + """Like _VarintDecoder() but decodes signed values.""" + + local_ord = ord + def DecodeVarint(buffer, pos): + result = 0 + shift = 0 + while 1: + b = local_ord(buffer[pos]) + result |= ((b & 0x7f) << shift) + pos += 1 + if not (b & 0x80): + if result > 0x7fffffffffffffff: + result -= (1 << 64) + result |= ~mask + else: + result &= mask + return (result, pos) + shift += 7 + if shift >= 64: + raise _DecodeError('Too many bytes when decoding varint.') + return DecodeVarint + + +_DecodeVarint = _VarintDecoder((1 << 64) - 1) +_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1) + +# Use these versions for values which must be limited to 32 bits. +_DecodeVarint32 = _VarintDecoder((1 << 32) - 1) +_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1) + + +def ReadTag(buffer, pos): + """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple. + + We return the raw bytes of the tag rather than decoding them. The raw + bytes can then be used to look up the proper decoder. This effectively allows + us to trade some work that would be done in pure-python (decoding a varint) + for work that is done in C (searching for a byte string in a hash table). + In a low-level language it would be much cheaper to decode the varint and + use that, but not in Python. + """ + + start = pos + while ord(buffer[pos]) & 0x80: + pos += 1 + pos += 1 + return (buffer[start:pos], pos) + + +# -------------------------------------------------------------------- + + +def _SimpleDecoder(wire_type, decode_value): + """Return a constructor for a decoder for fields of a particular type. + + Args: + wire_type: The field's wire type. + decode_value: A function which decodes an individual value, e.g. + _DecodeVarint() + """ + + def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default): + if is_packed: + local_DecodeVarint = _DecodeVarint + def DecodePackedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + (endpoint, pos) = local_DecodeVarint(buffer, pos) + endpoint += pos + if endpoint > end: + raise _DecodeError('Truncated message.') + while pos < endpoint: + (element, pos) = decode_value(buffer, pos) + value.append(element) + if pos > endpoint: + del value[-1] # Discard corrupt value. + raise _DecodeError('Packed element was truncated.') + return pos + return DecodePackedField + elif is_repeated: + tag_bytes = encoder.TagBytes(field_number, wire_type) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + (element, new_pos) = decode_value(buffer, pos) + value.append(element) + # Predict that the next tag is another copy of the same repeated + # field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos >= end: + # Prediction failed. Return. + if new_pos > end: + raise _DecodeError('Truncated message.') + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + (field_dict[key], pos) = decode_value(buffer, pos) + if pos > end: + del field_dict[key] # Discard corrupt value. + raise _DecodeError('Truncated message.') + return pos + return DecodeField + + return SpecificDecoder + + +def _ModifiedDecoder(wire_type, decode_value, modify_value): + """Like SimpleDecoder but additionally invokes modify_value on every value + before storing it. Usually modify_value is ZigZagDecode. + """ + + # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but + # not enough to make a significant difference. + + def InnerDecode(buffer, pos): + (result, new_pos) = decode_value(buffer, pos) + return (modify_value(result), new_pos) + return _SimpleDecoder(wire_type, InnerDecode) + + +def _StructPackDecoder(wire_type, format): + """Return a constructor for a decoder for a fixed-width field. + + Args: + wire_type: The field's wire type. + format: The format string to pass to struct.unpack(). + """ + + value_size = struct.calcsize(format) + local_unpack = struct.unpack + + # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but + # not enough to make a significant difference. + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + + def InnerDecode(buffer, pos): + new_pos = pos + value_size + result = local_unpack(format, buffer[pos:new_pos])[0] + return (result, new_pos) + return _SimpleDecoder(wire_type, InnerDecode) + + +# -------------------------------------------------------------------- + + +Int32Decoder = EnumDecoder = _SimpleDecoder( + wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32) + +Int64Decoder = _SimpleDecoder( + wire_format.WIRETYPE_VARINT, _DecodeSignedVarint) + +UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) +UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint) + +SInt32Decoder = _ModifiedDecoder( + wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode) +SInt64Decoder = _ModifiedDecoder( + wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode) + +# Note that Python conveniently guarantees that when using the '<' prefix on +# formats, they will also have the same size across all platforms (as opposed +# to without the prefix, where their sizes depend on the C compiler's basic +# type sizes). +Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<I') +Fixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<Q') +SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<i') +SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<q') +FloatDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<f') +DoubleDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<d') + +BoolDecoder = _ModifiedDecoder( + wire_format.WIRETYPE_VARINT, _DecodeVarint, bool) + + +def StringDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a string field.""" + + local_DecodeVarint = _DecodeVarint + local_unicode = unicode + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_LENGTH_DELIMITED) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + value.append(local_unicode(buffer[pos:new_pos], 'utf-8')) + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8') + return new_pos + return DecodeField + + +def BytesDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a bytes field.""" + + local_DecodeVarint = _DecodeVarint + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_LENGTH_DELIMITED) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + value.append(buffer[pos:new_pos]) + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + field_dict[key] = buffer[pos:new_pos] + return new_pos + return DecodeField + + +def GroupDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a group field.""" + + end_tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_END_GROUP) + end_tag_len = len(end_tag_bytes) + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_START_GROUP) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read sub-message. + pos = value.add()._InternalParse(buffer, pos, end) + # Read end tag. + new_pos = pos+end_tag_len + if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: + raise _DecodeError('Missing group end tag.') + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read sub-message. + pos = value._InternalParse(buffer, pos, end) + # Read end tag. + new_pos = pos+end_tag_len + if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: + raise _DecodeError('Missing group end tag.') + return new_pos + return DecodeField + + +def MessageDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a message field.""" + + local_DecodeVarint = _DecodeVarint + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, + wire_format.WIRETYPE_LENGTH_DELIMITED) + tag_len = len(tag_bytes) + def DecodeRepeatedField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read length. + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated message.') + # Read sub-message. + if value.add()._InternalParse(buffer, pos, new_pos) != new_pos: + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + return DecodeRepeatedField + else: + def DecodeField(buffer, pos, end, message, field_dict): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read length. + (size, pos) = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated message.') + # Read sub-message. + if value._InternalParse(buffer, pos, new_pos) != new_pos: + # The only reason _InternalParse would return early is if it encountered + # an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + return new_pos + return DecodeField + + +# -------------------------------------------------------------------- + +MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP) + +def MessageSetItemDecoder(extensions_by_number): + """Returns a decoder for a MessageSet item. + + The parameter is the _extensions_by_number map for the message class. + + The message set message looks like this: + message MessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required string message = 3; + } + } + """ + + type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) + message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) + item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) + + local_ReadTag = ReadTag + local_DecodeVarint = _DecodeVarint + local_SkipField = SkipField + + def DecodeItem(buffer, pos, end, message, field_dict): + type_id = -1 + message_start = -1 + message_end = -1 + + # Technically, type_id and message can appear in any order, so we need + # a little loop here. + while 1: + (tag_bytes, pos) = local_ReadTag(buffer, pos) + if tag_bytes == type_id_tag_bytes: + (type_id, pos) = local_DecodeVarint(buffer, pos) + elif tag_bytes == message_tag_bytes: + (size, message_start) = local_DecodeVarint(buffer, pos) + pos = message_end = message_start + size + elif tag_bytes == item_end_tag_bytes: + break + else: + pos = SkipField(buffer, pos, end, tag_bytes) + if pos == -1: + raise _DecodeError('Missing group end tag.') + + if pos > end: + raise _DecodeError('Truncated message.') + + if type_id == -1: + raise _DecodeError('MessageSet item missing type_id.') + if message_start == -1: + raise _DecodeError('MessageSet item missing message.') + + extension = extensions_by_number.get(type_id) + if extension is not None: + value = field_dict.get(extension) + if value is None: + value = field_dict.setdefault( + extension, extension.message_type._concrete_class()) + if value._InternalParse(buffer, message_start,message_end) != message_end: + # The only reason _InternalParse would return early is if it encountered + # an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + + return pos + + return DecodeItem + +# -------------------------------------------------------------------- +# Optimization is not as heavy here because calls to SkipField() are rare, +# except for handling end-group tags. + +def _SkipVarint(buffer, pos, end): + """Skip a varint value. Returns the new position.""" + + while ord(buffer[pos]) & 0x80: + pos += 1 + pos += 1 + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _SkipFixed64(buffer, pos, end): + """Skip a fixed64 value. Returns the new position.""" + + pos += 8 + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _SkipLengthDelimited(buffer, pos, end): + """Skip a length-delimited value. Returns the new position.""" + + (size, pos) = _DecodeVarint(buffer, pos) + pos += size + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _SkipGroup(buffer, pos, end): + """Skip sub-group. Returns the new position.""" + + while 1: + (tag_bytes, pos) = ReadTag(buffer, pos) + new_pos = SkipField(buffer, pos, end, tag_bytes) + if new_pos == -1: + return pos + pos = new_pos + +def _EndGroup(buffer, pos, end): + """Skipping an END_GROUP tag returns -1 to tell the parent loop to break.""" + + return -1 + +def _SkipFixed32(buffer, pos, end): + """Skip a fixed32 value. Returns the new position.""" + + pos += 4 + if pos > end: + raise _DecodeError('Truncated message.') + return pos + +def _RaiseInvalidWireType(buffer, pos, end): + """Skip function for unknown wire types. Raises an exception.""" + + raise _DecodeError('Tag had invalid wire type.') + +def _FieldSkipper(): + """Constructs the SkipField function.""" + + WIRETYPE_TO_SKIPPER = [ + _SkipVarint, + _SkipFixed64, + _SkipLengthDelimited, + _SkipGroup, + _EndGroup, + _SkipFixed32, + _RaiseInvalidWireType, + _RaiseInvalidWireType, + ] + + wiretype_mask = wire_format.TAG_TYPE_MASK + local_ord = ord + + def SkipField(buffer, pos, end, tag_bytes): + """Skips a field with the specified tag. + + |pos| should point to the byte immediately after the tag. + + Returns: + The new position (after the tag value), or -1 if the tag is an end-group + tag (in which case the calling loop should break). + """ -# Note that much of this code is ported from //net/proto/ProtocolBuffer, and -# that the interface is strongly inspired by WireFormat from the C++ proto2 -# implementation. - - -class Decoder(object): - - """Decodes logical protocol buffer fields from the wire.""" + # The wire type is always in the first byte since varints are little-endian. + wire_type = local_ord(tag_bytes[0]) & wiretype_mask + return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end) - def __init__(self, s): - """Initializes the decoder to read from s. + return SkipField - Args: - s: An immutable sequence of bytes, which must be accessible - via the Python buffer() primitive (i.e., buffer(s)). - """ - self._stream = input_stream.InputStream(s) - - def EndOfStream(self): - """Returns true iff we've reached the end of the bytes we're reading.""" - return self._stream.EndOfStream() - - def Position(self): - """Returns the 0-indexed position in |s|.""" - return self._stream.Position() - - def ReadFieldNumberAndWireType(self): - """Reads a tag from the wire. Returns a (field_number, wire_type) pair.""" - tag_and_type = self.ReadUInt32() - return wire_format.UnpackTag(tag_and_type) - - def SkipBytes(self, bytes): - """Skips the specified number of bytes on the wire.""" - self._stream.SkipBytes(bytes) - - # Note that the Read*() methods below are not exactly symmetrical with the - # corresponding Encoder.Append*() methods. Those Encoder methods first - # encode a tag, but the Read*() methods below assume that the tag has already - # been read, and that the client wishes to read a field of the specified type - # starting at the current position. - - def ReadInt32(self): - """Reads and returns a signed, varint-encoded, 32-bit integer.""" - return self._stream.ReadVarint32() - - def ReadInt64(self): - """Reads and returns a signed, varint-encoded, 64-bit integer.""" - return self._stream.ReadVarint64() - - def ReadUInt32(self): - """Reads and returns an signed, varint-encoded, 32-bit integer.""" - return self._stream.ReadVarUInt32() - - def ReadUInt64(self): - """Reads and returns an signed, varint-encoded,64-bit integer.""" - return self._stream.ReadVarUInt64() - - def ReadSInt32(self): - """Reads and returns a signed, zigzag-encoded, varint-encoded, - 32-bit integer.""" - return wire_format.ZigZagDecode(self._stream.ReadVarUInt32()) - - def ReadSInt64(self): - """Reads and returns a signed, zigzag-encoded, varint-encoded, - 64-bit integer.""" - return wire_format.ZigZagDecode(self._stream.ReadVarUInt64()) - - def ReadFixed32(self): - """Reads and returns an unsigned, fixed-width, 32-bit integer.""" - return self._stream.ReadLittleEndian32() - - def ReadFixed64(self): - """Reads and returns an unsigned, fixed-width, 64-bit integer.""" - return self._stream.ReadLittleEndian64() - - def ReadSFixed32(self): - """Reads and returns a signed, fixed-width, 32-bit integer.""" - value = self._stream.ReadLittleEndian32() - if value >= (1 << 31): - value -= (1 << 32) - return value - - def ReadSFixed64(self): - """Reads and returns a signed, fixed-width, 64-bit integer.""" - value = self._stream.ReadLittleEndian64() - if value >= (1 << 63): - value -= (1 << 64) - return value - - def ReadFloat(self): - """Reads and returns a 4-byte floating-point number.""" - serialized = self._stream.ReadBytes(4) - return struct.unpack(wire_format.FORMAT_FLOAT_LITTLE_ENDIAN, serialized)[0] - - def ReadDouble(self): - """Reads and returns an 8-byte floating-point number.""" - serialized = self._stream.ReadBytes(8) - return struct.unpack(wire_format.FORMAT_DOUBLE_LITTLE_ENDIAN, serialized)[0] - - def ReadBool(self): - """Reads and returns a bool.""" - i = self._stream.ReadVarUInt32() - return bool(i) - - def ReadEnum(self): - """Reads and returns an enum value.""" - return self._stream.ReadVarUInt32() - - def ReadString(self): - """Reads and returns a length-delimited string.""" - bytes = self.ReadBytes() - return unicode(bytes, 'utf-8') - - def ReadBytes(self): - """Reads and returns a length-delimited byte sequence.""" - length = self._stream.ReadVarUInt32() - return self._stream.ReadBytes(length) - - def ReadMessageInto(self, msg): - """Calls msg.MergeFromString() to merge - length-delimited serialized message data into |msg|. - - REQUIRES: The decoder must be positioned at the serialized "length" - prefix to a length-delmiited serialized message. - - POSTCONDITION: The decoder is positioned just after the - serialized message, and we have merged those serialized - contents into |msg|. - """ - length = self._stream.ReadVarUInt32() - sub_buffer = self._stream.GetSubBuffer(length) - num_bytes_used = msg.MergeFromString(sub_buffer) - if num_bytes_used != length: - raise message.DecodeError( - 'Submessage told to deserialize from %d-byte encoding, ' - 'but used only %d bytes' % (length, num_bytes_used)) - self._stream.SkipBytes(num_bytes_used) - - def ReadGroupInto(self, expected_field_number, group): - """Calls group.MergeFromString() to merge - END_GROUP-delimited serialized message data into |group|. - We'll raise an exception if we don't find an END_GROUP - tag immediately after the serialized message contents. - - REQUIRES: The decoder is positioned just after the START_GROUP - tag for this group. - - POSTCONDITION: The decoder is positioned just after the - END_GROUP tag for this group, and we have merged - the contents of the group into |group|. - """ - sub_buffer = self._stream.GetSubBuffer() # No a priori length limit. - num_bytes_used = group.MergeFromString(sub_buffer) - if num_bytes_used < 0: - raise message.DecodeError('Group message reported negative bytes read.') - self._stream.SkipBytes(num_bytes_used) - field_number, field_type = self.ReadFieldNumberAndWireType() - if field_type != wire_format.WIRETYPE_END_GROUP: - raise message.DecodeError('Group message did not end with an END_GROUP.') - if field_number != expected_field_number: - raise message.DecodeError('END_GROUP tag had field ' - 'number %d, was expecting field number %d' % ( - field_number, expected_field_number)) - # We're now positioned just after the END_GROUP tag. Perfect. +SkipField = _FieldSkipper() diff --git a/python/google/protobuf/internal/decoder_test.py b/python/google/protobuf/internal/decoder_test.py deleted file mode 100755 index 98e4647..0000000 --- a/python/google/protobuf/internal/decoder_test.py +++ /dev/null @@ -1,256 +0,0 @@ -#! /usr/bin/python -# -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# http://code.google.com/p/protobuf/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Test for google.protobuf.internal.decoder.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import struct -import unittest -from google.protobuf.internal import decoder -from google.protobuf.internal import encoder -from google.protobuf.internal import input_stream -from google.protobuf.internal import wire_format -from google.protobuf import message -import logging -import mox - - -class DecoderTest(unittest.TestCase): - - def setUp(self): - self.mox = mox.Mox() - self.mock_stream = self.mox.CreateMock(input_stream.InputStream) - self.mock_message = self.mox.CreateMock(message.Message) - - def testReadFieldNumberAndWireType(self): - # Test field numbers that will require various varint sizes. - for expected_field_number in (1, 15, 16, 2047, 2048): - for expected_wire_type in range(6): # Highest-numbered wiretype is 5. - e = encoder.Encoder() - e.AppendTag(expected_field_number, expected_wire_type) - s = e.ToString() - d = decoder.Decoder(s) - field_number, wire_type = d.ReadFieldNumberAndWireType() - self.assertEqual(expected_field_number, field_number) - self.assertEqual(expected_wire_type, wire_type) - - def ReadScalarTestHelper(self, test_name, decoder_method, expected_result, - expected_stream_method_name, - stream_method_return, *args): - """Helper for testReadScalars below. - - Calls one of the Decoder.Read*() methods and ensures that the results are - as expected. - - Args: - test_name: Name of this test, used for logging only. - decoder_method: Unbound decoder.Decoder method to call. - expected_result: Value we expect returned from decoder_method(). - expected_stream_method_name: (string) Name of the InputStream - method we expect Decoder to call to actually read the value - on the wire. - stream_method_return: Value our mocked-out stream method should - return to the decoder. - args: Additional arguments that we expect to be passed to the - stream method. - """ - logging.info('Testing %s scalar input.\n' - 'Calling %r(), and expecting that to call the ' - 'stream method %s(%r), which will return %r. Finally, ' - 'expecting the Decoder method to return %r'% ( - test_name, decoder_method, - expected_stream_method_name, args, stream_method_return, - expected_result)) - - d = decoder.Decoder('') - d._stream = self.mock_stream - if decoder_method in (decoder.Decoder.ReadString, - decoder.Decoder.ReadBytes): - self.mock_stream.ReadVarUInt32().AndReturn(len(stream_method_return)) - # We have to use names instead of methods to work around some - # mox weirdness. (ResetAll() is overzealous). - expected_stream_method = getattr(self.mock_stream, - expected_stream_method_name) - expected_stream_method(*args).AndReturn(stream_method_return) - - self.mox.ReplayAll() - result = decoder_method(d) - self.assertEqual(expected_result, result) - self.assert_(isinstance(result, type(expected_result))) - self.mox.VerifyAll() - self.mox.ResetAll() - - VAL = 1.125 # Perfectly representable as a float (no rounding error). - LITTLE_FLOAT_VAL = '\x00\x00\x90?' - LITTLE_DOUBLE_VAL = '\x00\x00\x00\x00\x00\x00\xf2?' - - def testReadScalars(self): - test_string = 'I can feel myself getting sutpider.' - scalar_tests = [ - ['int32', decoder.Decoder.ReadInt32, 0, 'ReadVarint32', 0], - ['int64', decoder.Decoder.ReadInt64, 0, 'ReadVarint64', 0], - ['uint32', decoder.Decoder.ReadUInt32, 0, 'ReadVarUInt32', 0], - ['uint64', decoder.Decoder.ReadUInt64, 0, 'ReadVarUInt64', 0], - ['fixed32', decoder.Decoder.ReadFixed32, 0xffffffff, - 'ReadLittleEndian32', 0xffffffff], - ['fixed64', decoder.Decoder.ReadFixed64, 0xffffffffffffffff, - 'ReadLittleEndian64', 0xffffffffffffffff], - ['sfixed32', decoder.Decoder.ReadSFixed32, long(-1), - 'ReadLittleEndian32', long(0xffffffff)], - ['sfixed64', decoder.Decoder.ReadSFixed64, long(-1), - 'ReadLittleEndian64', 0xffffffffffffffff], - ['float', decoder.Decoder.ReadFloat, self.VAL, - 'ReadBytes', self.LITTLE_FLOAT_VAL, 4], - ['double', decoder.Decoder.ReadDouble, self.VAL, - 'ReadBytes', self.LITTLE_DOUBLE_VAL, 8], - ['bool', decoder.Decoder.ReadBool, True, 'ReadVarUInt32', 1], - ['enum', decoder.Decoder.ReadEnum, 23, 'ReadVarUInt32', 23], - ['string', decoder.Decoder.ReadString, - unicode(test_string, 'utf-8'), 'ReadBytes', test_string, - len(test_string)], - ['utf8-string', decoder.Decoder.ReadString, - unicode(test_string, 'utf-8'), 'ReadBytes', test_string, - len(test_string)], - ['bytes', decoder.Decoder.ReadBytes, - test_string, 'ReadBytes', test_string, len(test_string)], - # We test zigzag decoding routines more extensively below. - ['sint32', decoder.Decoder.ReadSInt32, -1, 'ReadVarUInt32', 1], - ['sint64', decoder.Decoder.ReadSInt64, -1, 'ReadVarUInt64', 1], - ] - # Ensure that we're testing different Decoder methods and using - # different test names in all test cases above. - self.assertEqual(len(scalar_tests), len(set(t[0] for t in scalar_tests))) - self.assert_(len(scalar_tests) >= len(set(t[1] for t in scalar_tests))) - for args in scalar_tests: - self.ReadScalarTestHelper(*args) - - def testReadMessageInto(self): - length = 23 - def Test(simulate_error): - d = decoder.Decoder('') - d._stream = self.mock_stream - self.mock_stream.ReadVarUInt32().AndReturn(length) - sub_buffer = object() - self.mock_stream.GetSubBuffer(length).AndReturn(sub_buffer) - - if simulate_error: - self.mock_message.MergeFromString(sub_buffer).AndReturn(length - 1) - self.mox.ReplayAll() - self.assertRaises( - message.DecodeError, d.ReadMessageInto, self.mock_message) - else: - self.mock_message.MergeFromString(sub_buffer).AndReturn(length) - self.mock_stream.SkipBytes(length) - self.mox.ReplayAll() - d.ReadMessageInto(self.mock_message) - - self.mox.VerifyAll() - self.mox.ResetAll() - - Test(simulate_error=False) - Test(simulate_error=True) - - def testReadGroupInto_Success(self): - # Test both the empty and nonempty cases. - for num_bytes in (5, 0): - field_number = expected_field_number = 10 - d = decoder.Decoder('') - d._stream = self.mock_stream - sub_buffer = object() - self.mock_stream.GetSubBuffer().AndReturn(sub_buffer) - self.mock_message.MergeFromString(sub_buffer).AndReturn(num_bytes) - self.mock_stream.SkipBytes(num_bytes) - self.mock_stream.ReadVarUInt32().AndReturn(wire_format.PackTag( - field_number, wire_format.WIRETYPE_END_GROUP)) - self.mox.ReplayAll() - d.ReadGroupInto(expected_field_number, self.mock_message) - self.mox.VerifyAll() - self.mox.ResetAll() - - def ReadGroupInto_FailureTestHelper(self, bytes_read): - d = decoder.Decoder('') - d._stream = self.mock_stream - sub_buffer = object() - self.mock_stream.GetSubBuffer().AndReturn(sub_buffer) - self.mock_message.MergeFromString(sub_buffer).AndReturn(bytes_read) - return d - - def testReadGroupInto_NegativeBytesReported(self): - expected_field_number = 10 - d = self.ReadGroupInto_FailureTestHelper(bytes_read=-1) - self.mox.ReplayAll() - self.assertRaises(message.DecodeError, - d.ReadGroupInto, expected_field_number, - self.mock_message) - self.mox.VerifyAll() - - def testReadGroupInto_NoEndGroupTag(self): - field_number = expected_field_number = 10 - num_bytes = 5 - d = self.ReadGroupInto_FailureTestHelper(bytes_read=num_bytes) - self.mock_stream.SkipBytes(num_bytes) - # Right field number, wrong wire type. - self.mock_stream.ReadVarUInt32().AndReturn(wire_format.PackTag( - field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)) - self.mox.ReplayAll() - self.assertRaises(message.DecodeError, - d.ReadGroupInto, expected_field_number, - self.mock_message) - self.mox.VerifyAll() - - def testReadGroupInto_WrongFieldNumberInEndGroupTag(self): - expected_field_number = 10 - field_number = expected_field_number + 1 - num_bytes = 5 - d = self.ReadGroupInto_FailureTestHelper(bytes_read=num_bytes) - self.mock_stream.SkipBytes(num_bytes) - # Wrong field number, right wire type. - self.mock_stream.ReadVarUInt32().AndReturn(wire_format.PackTag( - field_number, wire_format.WIRETYPE_END_GROUP)) - self.mox.ReplayAll() - self.assertRaises(message.DecodeError, - d.ReadGroupInto, expected_field_number, - self.mock_message) - self.mox.VerifyAll() - - def testSkipBytes(self): - d = decoder.Decoder('') - num_bytes = 1024 - self.mock_stream.SkipBytes(num_bytes) - d._stream = self.mock_stream - self.mox.ReplayAll() - d.SkipBytes(num_bytes) - self.mox.VerifyAll() - -if __name__ == '__main__': - unittest.main() diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index eb9f2be..05c2745 100755 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -35,16 +35,30 @@ __author__ = 'robinson@google.com (Will Robinson)' import unittest +from google.protobuf import unittest_import_pb2 +from google.protobuf import unittest_pb2 from google.protobuf import descriptor_pb2 from google.protobuf import descriptor +from google.protobuf import text_format + + +TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """ +name: 'TestEmptyMessage' +""" + class DescriptorTest(unittest.TestCase): def setUp(self): + self.my_file = descriptor.FileDescriptor( + name='some/filename/some.proto', + package='protobuf_unittest' + ) self.my_enum = descriptor.EnumDescriptor( name='ForeignEnum', full_name='protobuf_unittest.ForeignEnum', - filename='ForeignEnum', + filename=None, + file=self.my_file, values=[ descriptor.EnumValueDescriptor(name='FOREIGN_FOO', index=0, number=4), descriptor.EnumValueDescriptor(name='FOREIGN_BAR', index=1, number=5), @@ -53,7 +67,8 @@ class DescriptorTest(unittest.TestCase): self.my_message = descriptor.Descriptor( name='NestedMessage', full_name='protobuf_unittest.TestAllTypes.NestedMessage', - filename='some/filename/some.proto', + filename=None, + file=self.my_file, containing_type=None, fields=[ descriptor.FieldDescriptor( @@ -61,7 +76,7 @@ class DescriptorTest(unittest.TestCase): full_name='protobuf_unittest.TestAllTypes.NestedMessage.bb', index=0, number=1, type=5, cpp_type=1, label=1, - default_value=0, + has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None), ], @@ -80,6 +95,7 @@ class DescriptorTest(unittest.TestCase): self.my_service = descriptor.ServiceDescriptor( name='TestServiceWithOptions', full_name='protobuf_unittest.TestServiceWithOptions', + file=self.my_file, index=0, methods=[ self.my_method @@ -109,5 +125,210 @@ class DescriptorTest(unittest.TestCase): self.assertEqual(self.my_service.GetOptions(), descriptor_pb2.ServiceOptions()) + def testFileDescriptorReferences(self): + self.assertEqual(self.my_enum.file, self.my_file) + self.assertEqual(self.my_message.file, self.my_file) + + def testFileDescriptor(self): + self.assertEqual(self.my_file.name, 'some/filename/some.proto') + self.assertEqual(self.my_file.package, 'protobuf_unittest') + + +class DescriptorCopyToProtoTest(unittest.TestCase): + """Tests for CopyTo functions of Descriptor.""" + + def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii): + expected_proto = expected_class() + text_format.Merge(expected_ascii, expected_proto) + + self.assertEqual( + actual_proto, expected_proto, + 'Not equal,\nActual:\n%s\nExpected:\n%s\n' + % (str(actual_proto), str(expected_proto))) + + def _InternalTestCopyToProto(self, desc, expected_proto_class, + expected_proto_ascii): + actual = expected_proto_class() + desc.CopyToProto(actual) + self._AssertProtoEqual( + actual, expected_proto_class, expected_proto_ascii) + + def testCopyToProto_EmptyMessage(self): + self._InternalTestCopyToProto( + unittest_pb2.TestEmptyMessage.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII) + + def testCopyToProto_NestedMessage(self): + TEST_NESTED_MESSAGE_ASCII = """ + name: 'NestedMessage' + field: < + name: 'bb' + number: 1 + label: 1 # Optional + type: 5 # TYPE_INT32 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_NESTED_MESSAGE_ASCII) + + def testCopyToProto_ForeignNestedMessage(self): + TEST_FOREIGN_NESTED_ASCII = """ + name: 'TestForeignNested' + field: < + name: 'foreign_nested' + number: 1 + label: 1 # Optional + type: 11 # TYPE_MESSAGE + type_name: '.protobuf_unittest.TestAllTypes.NestedMessage' + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestForeignNested.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_FOREIGN_NESTED_ASCII) + + def testCopyToProto_ForeignEnum(self): + TEST_FOREIGN_ENUM_ASCII = """ + name: 'ForeignEnum' + value: < + name: 'FOREIGN_FOO' + number: 4 + > + value: < + name: 'FOREIGN_BAR' + number: 5 + > + value: < + name: 'FOREIGN_BAZ' + number: 6 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2._FOREIGNENUM, + descriptor_pb2.EnumDescriptorProto, + TEST_FOREIGN_ENUM_ASCII) + + def testCopyToProto_Options(self): + TEST_DEPRECATED_FIELDS_ASCII = """ + name: 'TestDeprecatedFields' + field: < + name: 'deprecated_int32' + number: 1 + label: 1 # Optional + type: 5 # TYPE_INT32 + options: < + deprecated: true + > + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestDeprecatedFields.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_DEPRECATED_FIELDS_ASCII) + + def testCopyToProto_AllExtensions(self): + TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """ + name: 'TestEmptyMessageWithExtensions' + extension_range: < + start: 1 + end: 536870912 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII) + + def testCopyToProto_SeveralExtensions(self): + TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """ + name: 'TestMultipleExtensionRanges' + extension_range: < + start: 42 + end: 43 + > + extension_range: < + start: 4143 + end: 4244 + > + extension_range: < + start: 65536 + end: 536870912 + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR, + descriptor_pb2.DescriptorProto, + TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII) + + def testCopyToProto_FileDescriptor(self): + UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = (""" + name: 'google/protobuf/unittest_import.proto' + package: 'protobuf_unittest_import' + message_type: < + name: 'ImportMessage' + field: < + name: 'd' + number: 1 + label: 1 # Optional + type: 5 # TYPE_INT32 + > + > + """ + + """enum_type: < + name: 'ImportEnum' + value: < + name: 'IMPORT_FOO' + number: 7 + > + value: < + name: 'IMPORT_BAR' + number: 8 + > + value: < + name: 'IMPORT_BAZ' + number: 9 + > + > + options: < + java_package: 'com.google.protobuf.test' + optimize_for: 1 # SPEED + > + """) + + self._InternalTestCopyToProto( + unittest_import_pb2.DESCRIPTOR, + descriptor_pb2.FileDescriptorProto, + UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII) + + def testCopyToProto_ServiceDescriptor(self): + TEST_SERVICE_ASCII = """ + name: 'TestService' + method: < + name: 'Foo' + input_type: '.protobuf_unittest.FooRequest' + output_type: '.protobuf_unittest.FooResponse' + > + method: < + name: 'Bar' + input_type: '.protobuf_unittest.BarRequest' + output_type: '.protobuf_unittest.BarResponse' + > + """ + + self._InternalTestCopyToProto( + unittest_pb2.TestService.DESCRIPTOR, + descriptor_pb2.ServiceDescriptorProto, + TEST_SERVICE_ASCII) + + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py index 3ec3b2b..aa05d5b 100755 --- a/python/google/protobuf/internal/encoder.py +++ b/python/google/protobuf/internal/encoder.py @@ -28,253 +28,659 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Class for encoding protocol message primitives. +"""Code for encoding protocol message primitives. Contains the logic for encoding every logical protocol field type into one of the 5 physical wire types. + +This code is designed to push the Python interpreter's performance to the +limits. + +The basic idea is that at startup time, for every field (i.e. every +FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The +sizer takes a value of this field's type and computes its byte size. The +encoder takes a writer function and a value. It encodes the value into byte +strings and invokes the writer function to write those strings. Typically the +writer function is the write() method of a cStringIO. + +We try to do as much work as possible when constructing the writer and the +sizer rather than when calling them. In particular: +* We copy any needed global functions to local variables, so that we do not need + to do costly global table lookups at runtime. +* Similarly, we try to do any attribute lookups at startup time if possible. +* Every field's tag is encoded to bytes at startup, since it can't change at + runtime. +* Whatever component of the field size we can compute at startup, we do. +* We *avoid* sharing code if doing so would make the code slower and not sharing + does not burden us too much. For example, encoders for repeated fields do + not just call the encoders for singular fields in a loop because this would + add an extra function call overhead for every loop iteration; instead, we + manually inline the single-value encoder into the loop. +* If a Python function lacks a return statement, Python actually generates + instructions to pop the result of the last statement off the stack, push + None onto the stack, and then return that. If we really don't care what + value is returned, then we can save two instructions by returning the + result of the last statement. It looks funny but it helps. +* We assume that type and bounds checking has happened at a higher level. """ -__author__ = 'robinson@google.com (Will Robinson)' +__author__ = 'kenton@google.com (Kenton Varda)' import struct -from google.protobuf import message from google.protobuf.internal import wire_format -from google.protobuf.internal import output_stream - - -# Note that much of this code is ported from //net/proto/ProtocolBuffer, and -# that the interface is strongly inspired by WireFormat from the C++ proto2 -# implementation. - - -class Encoder(object): - - """Encodes logical protocol buffer fields to the wire format.""" - - def __init__(self): - self._stream = output_stream.OutputStream() - - def ToString(self): - """Returns all values encoded in this object as a string.""" - return self._stream.ToString() - - # Append*NoTag methods. These are necessary for serializing packed - # repeated fields. The Append*() methods call these methods to do - # the actual serialization. - def AppendInt32NoTag(self, value): - """Appends a 32-bit integer to our buffer, varint-encoded.""" - self._stream.AppendVarint32(value) - - def AppendInt64NoTag(self, value): - """Appends a 64-bit integer to our buffer, varint-encoded.""" - self._stream.AppendVarint64(value) - - def AppendUInt32NoTag(self, unsigned_value): - """Appends an unsigned 32-bit integer to our buffer, varint-encoded.""" - self._stream.AppendVarUInt32(unsigned_value) - - def AppendUInt64NoTag(self, unsigned_value): - """Appends an unsigned 64-bit integer to our buffer, varint-encoded.""" - self._stream.AppendVarUInt64(unsigned_value) - - def AppendSInt32NoTag(self, value): - """Appends a 32-bit integer to our buffer, zigzag-encoded and then - varint-encoded. - """ - zigzag_value = wire_format.ZigZagEncode(value) - self._stream.AppendVarUInt32(zigzag_value) - - def AppendSInt64NoTag(self, value): - """Appends a 64-bit integer to our buffer, zigzag-encoded and then - varint-encoded. - """ - zigzag_value = wire_format.ZigZagEncode(value) - self._stream.AppendVarUInt64(zigzag_value) - - def AppendFixed32NoTag(self, unsigned_value): - """Appends an unsigned 32-bit integer to our buffer, in little-endian - byte-order. - """ - self._stream.AppendLittleEndian32(unsigned_value) - - def AppendFixed64NoTag(self, unsigned_value): - """Appends an unsigned 64-bit integer to our buffer, in little-endian - byte-order. - """ - self._stream.AppendLittleEndian64(unsigned_value) - - def AppendSFixed32NoTag(self, value): - """Appends a signed 32-bit integer to our buffer, in little-endian - byte-order. - """ - sign = (value & 0x80000000) and -1 or 0 - if value >> 32 != sign: - raise message.EncodeError('SFixed32 out of range: %d' % value) - self._stream.AppendLittleEndian32(value & 0xffffffff) - - def AppendSFixed64NoTag(self, value): - """Appends a signed 64-bit integer to our buffer, in little-endian - byte-order. - """ - sign = (value & 0x8000000000000000) and -1 or 0 - if value >> 64 != sign: - raise message.EncodeError('SFixed64 out of range: %d' % value) - self._stream.AppendLittleEndian64(value & 0xffffffffffffffff) - - def AppendFloatNoTag(self, value): - """Appends a floating-point number to our buffer.""" - self._stream.AppendRawBytes( - struct.pack(wire_format.FORMAT_FLOAT_LITTLE_ENDIAN, value)) - - def AppendDoubleNoTag(self, value): - """Appends a double-precision floating-point number to our buffer.""" - self._stream.AppendRawBytes( - struct.pack(wire_format.FORMAT_DOUBLE_LITTLE_ENDIAN, value)) - - def AppendBoolNoTag(self, value): - """Appends a boolean to our buffer.""" - self.AppendInt32NoTag(value) - - def AppendEnumNoTag(self, value): - """Appends an enum value to our buffer.""" - self.AppendInt32NoTag(value) - - - # All the Append*() methods below first append a tag+type pair to the buffer - # before appending the specified value. - - def AppendInt32(self, field_number, value): - """Appends a 32-bit integer to our buffer, varint-encoded.""" - self.AppendTag(field_number, wire_format.WIRETYPE_VARINT) - self.AppendInt32NoTag(value) - - def AppendInt64(self, field_number, value): - """Appends a 64-bit integer to our buffer, varint-encoded.""" - self.AppendTag(field_number, wire_format.WIRETYPE_VARINT) - self.AppendInt64NoTag(value) - - def AppendUInt32(self, field_number, unsigned_value): - """Appends an unsigned 32-bit integer to our buffer, varint-encoded.""" - self.AppendTag(field_number, wire_format.WIRETYPE_VARINT) - self.AppendUInt32NoTag(unsigned_value) - - def AppendUInt64(self, field_number, unsigned_value): - """Appends an unsigned 64-bit integer to our buffer, varint-encoded.""" - self.AppendTag(field_number, wire_format.WIRETYPE_VARINT) - self.AppendUInt64NoTag(unsigned_value) - - def AppendSInt32(self, field_number, value): - """Appends a 32-bit integer to our buffer, zigzag-encoded and then - varint-encoded. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_VARINT) - self.AppendSInt32NoTag(value) - - def AppendSInt64(self, field_number, value): - """Appends a 64-bit integer to our buffer, zigzag-encoded and then - varint-encoded. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_VARINT) - self.AppendSInt64NoTag(value) - - def AppendFixed32(self, field_number, unsigned_value): - """Appends an unsigned 32-bit integer to our buffer, in little-endian - byte-order. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_FIXED32) - self.AppendFixed32NoTag(unsigned_value) - - def AppendFixed64(self, field_number, unsigned_value): - """Appends an unsigned 64-bit integer to our buffer, in little-endian - byte-order. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_FIXED64) - self.AppendFixed64NoTag(unsigned_value) - - def AppendSFixed32(self, field_number, value): - """Appends a signed 32-bit integer to our buffer, in little-endian - byte-order. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_FIXED32) - self.AppendSFixed32NoTag(value) - - def AppendSFixed64(self, field_number, value): - """Appends a signed 64-bit integer to our buffer, in little-endian - byte-order. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_FIXED64) - self.AppendSFixed64NoTag(value) - - def AppendFloat(self, field_number, value): - """Appends a floating-point number to our buffer.""" - self.AppendTag(field_number, wire_format.WIRETYPE_FIXED32) - self.AppendFloatNoTag(value) - - def AppendDouble(self, field_number, value): - """Appends a double-precision floating-point number to our buffer.""" - self.AppendTag(field_number, wire_format.WIRETYPE_FIXED64) - self.AppendDoubleNoTag(value) - - def AppendBool(self, field_number, value): - """Appends a boolean to our buffer.""" - self.AppendInt32(field_number, value) - - def AppendEnum(self, field_number, value): - """Appends an enum value to our buffer.""" - self.AppendInt32(field_number, value) - - def AppendString(self, field_number, value): - """Appends a length-prefixed unicode string, encoded as UTF-8 to our buffer, - with the length varint-encoded. - """ - self.AppendBytes(field_number, value.encode('utf-8')) - - def AppendBytes(self, field_number, value): - """Appends a length-prefixed sequence of bytes to our buffer, with the - length varint-encoded. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - self._stream.AppendVarUInt32(len(value)) - self._stream.AppendRawBytes(value) - - # TODO(robinson): For AppendGroup() and AppendMessage(), we'd really like to - # avoid the extra string copy here. We can do so if we widen the Message - # interface to be able to serialize to a stream in addition to a string. The - # challenge when thinking ahead to the Python/C API implementation of Message - # is finding a stream-like Python thing to which we can write raw bytes - # from C. I'm not sure such a thing exists(?). (array.array is pretty much - # what we want, but it's not directly exposed in the Python/C API). - - def AppendGroup(self, field_number, group): - """Appends a group to our buffer. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_START_GROUP) - self._stream.AppendRawBytes(group.SerializeToString()) - self.AppendTag(field_number, wire_format.WIRETYPE_END_GROUP) - - def AppendMessage(self, field_number, msg): - """Appends a nested message to our buffer. - """ - self.AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - self._stream.AppendVarUInt32(msg.ByteSize()) - self._stream.AppendRawBytes(msg.SerializeToString()) - - def AppendMessageSetItem(self, field_number, msg): - """Appends an item using the message set wire format. - - The message set message looks like this: - message MessageSet { - repeated group Item = 1 { - required int32 type_id = 2; - required string message = 3; - } + + +def _VarintSize(value): + """Compute the size of a varint value.""" + if value <= 0x7f: return 1 + if value <= 0x3fff: return 2 + if value <= 0x1fffff: return 3 + if value <= 0xfffffff: return 4 + if value <= 0x7ffffffff: return 5 + if value <= 0x3ffffffffff: return 6 + if value <= 0x1ffffffffffff: return 7 + if value <= 0xffffffffffffff: return 8 + if value <= 0x7fffffffffffffff: return 9 + return 10 + + +def _SignedVarintSize(value): + """Compute the size of a signed varint value.""" + if value < 0: return 10 + if value <= 0x7f: return 1 + if value <= 0x3fff: return 2 + if value <= 0x1fffff: return 3 + if value <= 0xfffffff: return 4 + if value <= 0x7ffffffff: return 5 + if value <= 0x3ffffffffff: return 6 + if value <= 0x1ffffffffffff: return 7 + if value <= 0xffffffffffffff: return 8 + if value <= 0x7fffffffffffffff: return 9 + return 10 + + +def _TagSize(field_number): + """Returns the number of bytes required to serialize a tag with this field + number.""" + # Just pass in type 0, since the type won't affect the tag+type size. + return _VarintSize(wire_format.PackTag(field_number, 0)) + + +# -------------------------------------------------------------------- +# In this section we define some generic sizers. Each of these functions +# takes parameters specific to a particular field type, e.g. int32 or fixed64. +# It returns another function which in turn takes parameters specific to a +# particular field, e.g. the field number and whether it is repeated or packed. +# Look at the next section to see how these are used. + + +def _SimpleSizer(compute_value_size): + """A sizer which uses the function compute_value_size to compute the size of + each value. Typically compute_value_size is _VarintSize.""" + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + def PackedFieldSize(value): + result = 0 + for element in value: + result += compute_value_size(element) + return result + local_VarintSize(result) + tag_size + return PackedFieldSize + elif is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += compute_value_size(element) + return result + return RepeatedFieldSize + else: + def FieldSize(value): + return tag_size + compute_value_size(value) + return FieldSize + + return SpecificSizer + + +def _ModifiedSizer(compute_value_size, modify_value): + """Like SimpleSizer, but modify_value is invoked on each value before it is + passed to compute_value_size. modify_value is typically ZigZagEncode.""" + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + def PackedFieldSize(value): + result = 0 + for element in value: + result += compute_value_size(modify_value(element)) + return result + local_VarintSize(result) + tag_size + return PackedFieldSize + elif is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += compute_value_size(modify_value(element)) + return result + return RepeatedFieldSize + else: + def FieldSize(value): + return tag_size + compute_value_size(modify_value(value)) + return FieldSize + + return SpecificSizer + + +def _FixedSizer(value_size): + """Like _SimpleSizer except for a fixed-size field. The input is the size + of one value.""" + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + def PackedFieldSize(value): + result = len(value) * value_size + return result + local_VarintSize(result) + tag_size + return PackedFieldSize + elif is_repeated: + element_size = value_size + tag_size + def RepeatedFieldSize(value): + return len(value) * element_size + return RepeatedFieldSize + else: + field_size = value_size + tag_size + def FieldSize(value): + return field_size + return FieldSize + + return SpecificSizer + + +# ==================================================================== +# Here we declare a sizer constructor for each field type. Each "sizer +# constructor" is a function that takes (field_number, is_repeated, is_packed) +# as parameters and returns a sizer, which in turn takes a field value as +# a parameter and returns its encoded size. + + +Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize) + +UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize) + +SInt32Sizer = SInt64Sizer = _ModifiedSizer( + _SignedVarintSize, wire_format.ZigZagEncode) + +Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4) +Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8) + +BoolSizer = _FixedSizer(1) + + +def StringSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a string field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + local_len = len + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = local_len(element.encode('utf-8')) + result += local_VarintSize(l) + l + return result + return RepeatedFieldSize + else: + def FieldSize(value): + l = local_len(value.encode('utf-8')) + return tag_size + local_VarintSize(l) + l + return FieldSize + + +def BytesSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a bytes field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + local_len = len + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = local_len(element) + result += local_VarintSize(l) + l + return result + return RepeatedFieldSize + else: + def FieldSize(value): + l = local_len(value) + return tag_size + local_VarintSize(l) + l + return FieldSize + + +def GroupSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a group field.""" + + tag_size = _TagSize(field_number) * 2 + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += element.ByteSize() + return result + return RepeatedFieldSize + else: + def FieldSize(value): + return tag_size + value.ByteSize() + return FieldSize + + +def MessageSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a message field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + assert not is_packed + if is_repeated: + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = element.ByteSize() + result += local_VarintSize(l) + l + return result + return RepeatedFieldSize + else: + def FieldSize(value): + l = value.ByteSize() + return tag_size + local_VarintSize(l) + l + return FieldSize + + +# -------------------------------------------------------------------- +# MessageSet is special. + + +def MessageSetItemSizer(field_number): + """Returns a sizer for extensions of MessageSet. + + The message set message looks like this: + message MessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required string message = 3; + } + } + """ + static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) + + _TagSize(3)) + local_VarintSize = _VarintSize + + def FieldSize(value): + l = value.ByteSize() + return static_size + local_VarintSize(l) + l + + return FieldSize + + +# ==================================================================== +# Encoders! + + +def _VarintEncoder(): + """Return an encoder for a basic varint value (does not include tag).""" + + local_chr = chr + def EncodeVarint(write, value): + bits = value & 0x7f + value >>= 7 + while value: + write(local_chr(0x80|bits)) + bits = value & 0x7f + value >>= 7 + return write(local_chr(bits)) + + return EncodeVarint + + +def _SignedVarintEncoder(): + """Return an encoder for a basic signed varint value (does not include + tag).""" + + local_chr = chr + def EncodeSignedVarint(write, value): + if value < 0: + value += (1 << 64) + bits = value & 0x7f + value >>= 7 + while value: + write(local_chr(0x80|bits)) + bits = value & 0x7f + value >>= 7 + return write(local_chr(bits)) + + return EncodeSignedVarint + + +_EncodeVarint = _VarintEncoder() +_EncodeSignedVarint = _SignedVarintEncoder() + + +def _VarintBytes(value): + """Encode the given integer as a varint and return the bytes. This is only + called at startup time so it doesn't need to be fast.""" + + pieces = [] + _EncodeVarint(pieces.append, value) + return "".join(pieces) + + +def TagBytes(field_number, wire_type): + """Encode the given tag and return the bytes. Only called at startup.""" + + return _VarintBytes(wire_format.PackTag(field_number, wire_type)) + +# -------------------------------------------------------------------- +# As with sizers (see above), we have a number of common encoder +# implementations. + + +def _SimpleEncoder(wire_type, encode_value, compute_value_size): + """Return a constructor for an encoder for fields of a particular type. + + Args: + wire_type: The field's wire type, for encoding tags. + encode_value: A function which encodes an individual value, e.g. + _EncodeVarint(). + compute_value_size: A function which computes the size of an individual + value, e.g. _VarintSize(). + """ + + def SpecificEncoder(field_number, is_repeated, is_packed): + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + size = 0 + for element in value: + size += compute_value_size(element) + local_EncodeVarint(write, size) + for element in value: + encode_value(write, element) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + encode_value(write, element) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + return encode_value(write, value) + return EncodeField + + return SpecificEncoder + + +def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): + """Like SimpleEncoder but additionally invokes modify_value on every value + before passing it to encode_value. Usually modify_value is ZigZagEncode.""" + + def SpecificEncoder(field_number, is_repeated, is_packed): + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + size = 0 + for element in value: + size += compute_value_size(modify_value(element)) + local_EncodeVarint(write, size) + for element in value: + encode_value(write, modify_value(element)) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + encode_value(write, modify_value(element)) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + return encode_value(write, modify_value(value)) + return EncodeField + + return SpecificEncoder + + +def _StructPackEncoder(wire_type, format): + """Return a constructor for an encoder for a fixed-width field. + + Args: + wire_type: The field's wire type, for encoding tags. + format: The format string to pass to struct.pack(). + """ + + value_size = struct.calcsize(format) + + def SpecificEncoder(field_number, is_repeated, is_packed): + local_struct_pack = struct.pack + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + local_EncodeVarint(write, len(value) * value_size) + for element in value: + write(local_struct_pack(format, element)) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + write(local_struct_pack(format, element)) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + return write(local_struct_pack(format, value)) + return EncodeField + + return SpecificEncoder + + +# ==================================================================== +# Here we declare an encoder constructor for each field type. These work +# very similarly to sizer constructors, described earlier. + + +Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder( + wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize) + +UInt32Encoder = UInt64Encoder = _SimpleEncoder( + wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize) + +SInt32Encoder = SInt64Encoder = _ModifiedEncoder( + wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize, + wire_format.ZigZagEncode) + +# Note that Python conveniently guarantees that when using the '<' prefix on +# formats, they will also have the same size across all platforms (as opposed +# to without the prefix, where their sizes depend on the C compiler's basic +# type sizes). +Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I') +Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q') +SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i') +SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q') +FloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<f') +DoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<d') + + +def BoolEncoder(field_number, is_repeated, is_packed): + """Returns an encoder for a boolean field.""" + + false_byte = chr(0) + true_byte = chr(1) + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + local_EncodeVarint(write, len(value)) + for element in value: + if element: + write(true_byte) + else: + write(false_byte) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + if element: + write(true_byte) + else: + write(false_byte) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) + def EncodeField(write, value): + write(tag_bytes) + if value: + return write(true_byte) + return write(false_byte) + return EncodeField + + +def StringEncoder(field_number, is_repeated, is_packed): + """Returns an encoder for a string field.""" + + tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + local_len = len + assert not is_packed + if is_repeated: + def EncodeRepeatedField(write, value): + for element in value: + encoded = element.encode('utf-8') + write(tag) + local_EncodeVarint(write, local_len(encoded)) + write(encoded) + return EncodeRepeatedField + else: + def EncodeField(write, value): + encoded = value.encode('utf-8') + write(tag) + local_EncodeVarint(write, local_len(encoded)) + return write(encoded) + return EncodeField + + +def BytesEncoder(field_number, is_repeated, is_packed): + """Returns an encoder for a bytes field.""" + + tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + local_len = len + assert not is_packed + if is_repeated: + def EncodeRepeatedField(write, value): + for element in value: + write(tag) + local_EncodeVarint(write, local_len(element)) + write(element) + return EncodeRepeatedField + else: + def EncodeField(write, value): + write(tag) + local_EncodeVarint(write, local_len(value)) + return write(value) + return EncodeField + + +def GroupEncoder(field_number, is_repeated, is_packed): + """Returns an encoder for a group field.""" + + start_tag = TagBytes(field_number, wire_format.WIRETYPE_START_GROUP) + end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP) + assert not is_packed + if is_repeated: + def EncodeRepeatedField(write, value): + for element in value: + write(start_tag) + element._InternalSerialize(write) + write(end_tag) + return EncodeRepeatedField + else: + def EncodeField(write, value): + write(start_tag) + value._InternalSerialize(write) + return write(end_tag) + return EncodeField + + +def MessageEncoder(field_number, is_repeated, is_packed): + """Returns an encoder for a message field.""" + + tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + assert not is_packed + if is_repeated: + def EncodeRepeatedField(write, value): + for element in value: + write(tag) + local_EncodeVarint(write, element.ByteSize()) + element._InternalSerialize(write) + return EncodeRepeatedField + else: + def EncodeField(write, value): + write(tag) + local_EncodeVarint(write, value.ByteSize()) + return value._InternalSerialize(write) + return EncodeField + + +# -------------------------------------------------------------------- +# As before, MessageSet is special. + + +def MessageSetItemEncoder(field_number): + """Encoder for extensions of MessageSet. + + The message set message looks like this: + message MessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required string message = 3; } - """ - self.AppendTag(1, wire_format.WIRETYPE_START_GROUP) - self.AppendInt32(2, field_number) - self.AppendMessage(3, msg) - self.AppendTag(1, wire_format.WIRETYPE_END_GROUP) - - def AppendTag(self, field_number, wire_type): - """Appends a tag containing field number and wire type information.""" - self._stream.AppendVarUInt32(wire_format.PackTag(field_number, wire_type)) + } + """ + start_bytes = "".join([ + TagBytes(1, wire_format.WIRETYPE_START_GROUP), + TagBytes(2, wire_format.WIRETYPE_VARINT), + _VarintBytes(field_number), + TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)]) + end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP) + local_EncodeVarint = _EncodeVarint + + def EncodeField(write, value): + write(start_bytes) + local_EncodeVarint(write, value.ByteSize()) + value._InternalSerialize(write) + return write(end_bytes) + + return EncodeField diff --git a/python/google/protobuf/internal/encoder_test.py b/python/google/protobuf/internal/encoder_test.py deleted file mode 100755 index bf75ea8..0000000 --- a/python/google/protobuf/internal/encoder_test.py +++ /dev/null @@ -1,286 +0,0 @@ -#! /usr/bin/python -# -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# http://code.google.com/p/protobuf/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Test for google.protobuf.internal.encoder.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import struct -import logging -import unittest -from google.protobuf.internal import wire_format -from google.protobuf.internal import encoder -from google.protobuf.internal import output_stream -from google.protobuf import message -import mox - - -class EncoderTest(unittest.TestCase): - - def setUp(self): - self.mox = mox.Mox() - self.encoder = encoder.Encoder() - self.mock_stream = self.mox.CreateMock(output_stream.OutputStream) - self.mock_message = self.mox.CreateMock(message.Message) - self.encoder._stream = self.mock_stream - - def PackTag(self, field_number, wire_type): - return wire_format.PackTag(field_number, wire_type) - - def AppendScalarTestHelper(self, test_name, encoder_method, - expected_stream_method_name, - wire_type, field_value, - expected_value=None, expected_length=None, - is_tag_test=True): - """Helper for testAppendScalars. - - Calls one of the Encoder methods, and ensures that the Encoder - in turn makes the expected calls into its OutputStream. - - Args: - test_name: Name of this test, used only for logging. - encoder_method: Callable on self.encoder. This is the Encoder - method we're testing. If is_tag_test=True, the encoder method - accepts a field_number and field_value. if is_tag_test=False, - the encoder method accepts a field_value. - expected_stream_method_name: (string) Name of the OutputStream - method we expect Encoder to call to actually put the value - on the wire. - wire_type: The WIRETYPE_* constant we expect encoder to - use in the specified encoder_method. - field_value: The value we're trying to encode. Passed - into encoder_method. - expected_value: The value we expect Encoder to pass into - the OutputStream method. If None, we expect field_value - to pass through unmodified. - expected_length: The length we expect Encoder to pass to the - AppendVarUInt32 method. If None we expect the length of the - field_value. - is_tag_test: A Boolean. If True (the default), we append the - the packed field number and wire_type to the stream before - the field value. - """ - if expected_value is None: - expected_value = field_value - - logging.info('Testing %s scalar output.\n' - 'Calling %r(%r), and expecting that to call the ' - 'stream method %s(%r).' % ( - test_name, encoder_method, field_value, - expected_stream_method_name, expected_value)) - - if is_tag_test: - field_number = 10 - # Should first append the field number and type information. - self.mock_stream.AppendVarUInt32(self.PackTag(field_number, wire_type)) - # If we're length-delimited, we should then append the length. - if wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED: - if expected_length is None: - expected_length = len(field_value) - self.mock_stream.AppendVarUInt32(expected_length) - - # Should then append the value itself. - # We have to use names instead of methods to work around some - # mox weirdness. (ResetAll() is overzealous). - expected_stream_method = getattr(self.mock_stream, - expected_stream_method_name) - expected_stream_method(expected_value) - - self.mox.ReplayAll() - if is_tag_test: - encoder_method(field_number, field_value) - else: - encoder_method(field_value) - self.mox.VerifyAll() - self.mox.ResetAll() - - VAL = 1.125 # Perfectly representable as a float (no rounding error). - LITTLE_FLOAT_VAL = '\x00\x00\x90?' - LITTLE_DOUBLE_VAL = '\x00\x00\x00\x00\x00\x00\xf2?' - - def testAppendScalars(self): - utf8_bytes = '\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82' - utf8_string = unicode(utf8_bytes, 'utf-8') - scalar_tests = [ - ['int32', self.encoder.AppendInt32, 'AppendVarint32', - wire_format.WIRETYPE_VARINT, 0], - ['int64', self.encoder.AppendInt64, 'AppendVarint64', - wire_format.WIRETYPE_VARINT, 0], - ['uint32', self.encoder.AppendUInt32, 'AppendVarUInt32', - wire_format.WIRETYPE_VARINT, 0], - ['uint64', self.encoder.AppendUInt64, 'AppendVarUInt64', - wire_format.WIRETYPE_VARINT, 0], - ['fixed32', self.encoder.AppendFixed32, 'AppendLittleEndian32', - wire_format.WIRETYPE_FIXED32, 0], - ['fixed64', self.encoder.AppendFixed64, 'AppendLittleEndian64', - wire_format.WIRETYPE_FIXED64, 0], - ['sfixed32', self.encoder.AppendSFixed32, 'AppendLittleEndian32', - wire_format.WIRETYPE_FIXED32, -1, 0xffffffff], - ['sfixed64', self.encoder.AppendSFixed64, 'AppendLittleEndian64', - wire_format.WIRETYPE_FIXED64, -1, 0xffffffffffffffff], - ['float', self.encoder.AppendFloat, 'AppendRawBytes', - wire_format.WIRETYPE_FIXED32, self.VAL, self.LITTLE_FLOAT_VAL], - ['double', self.encoder.AppendDouble, 'AppendRawBytes', - wire_format.WIRETYPE_FIXED64, self.VAL, self.LITTLE_DOUBLE_VAL], - ['bool', self.encoder.AppendBool, 'AppendVarint32', - wire_format.WIRETYPE_VARINT, False], - ['enum', self.encoder.AppendEnum, 'AppendVarint32', - wire_format.WIRETYPE_VARINT, 0], - ['string', self.encoder.AppendString, 'AppendRawBytes', - wire_format.WIRETYPE_LENGTH_DELIMITED, - "You're in a maze of twisty little passages, all alike."], - ['utf8-string', self.encoder.AppendString, 'AppendRawBytes', - wire_format.WIRETYPE_LENGTH_DELIMITED, utf8_string, - utf8_bytes, len(utf8_bytes)], - # We test zigzag encoding routines more extensively below. - ['sint32', self.encoder.AppendSInt32, 'AppendVarUInt32', - wire_format.WIRETYPE_VARINT, -1, 1], - ['sint64', self.encoder.AppendSInt64, 'AppendVarUInt64', - wire_format.WIRETYPE_VARINT, -1, 1], - ] - # Ensure that we're testing different Encoder methods and using - # different test names in all test cases above. - self.assertEqual(len(scalar_tests), len(set(t[0] for t in scalar_tests))) - self.assert_(len(scalar_tests) >= len(set(t[1] for t in scalar_tests))) - for args in scalar_tests: - self.AppendScalarTestHelper(*args) - - def testAppendScalarsWithoutTags(self): - scalar_no_tag_tests = [ - ['int32', self.encoder.AppendInt32NoTag, 'AppendVarint32', None, 0], - ['int64', self.encoder.AppendInt64NoTag, 'AppendVarint64', None, 0], - ['uint32', self.encoder.AppendUInt32NoTag, 'AppendVarUInt32', None, 0], - ['uint64', self.encoder.AppendUInt64NoTag, 'AppendVarUInt64', None, 0], - ['fixed32', self.encoder.AppendFixed32NoTag, - 'AppendLittleEndian32', None, 0], - ['fixed64', self.encoder.AppendFixed64NoTag, - 'AppendLittleEndian64', None, 0], - ['sfixed32', self.encoder.AppendSFixed32NoTag, - 'AppendLittleEndian32', None, 0], - ['sfixed64', self.encoder.AppendSFixed64NoTag, - 'AppendLittleEndian64', None, 0], - ['float', self.encoder.AppendFloatNoTag, - 'AppendRawBytes', None, self.VAL, self.LITTLE_FLOAT_VAL], - ['double', self.encoder.AppendDoubleNoTag, - 'AppendRawBytes', None, self.VAL, self.LITTLE_DOUBLE_VAL], - ['bool', self.encoder.AppendBoolNoTag, 'AppendVarint32', None, 0], - ['enum', self.encoder.AppendEnumNoTag, 'AppendVarint32', None, 0], - ['sint32', self.encoder.AppendSInt32NoTag, - 'AppendVarUInt32', None, -1, 1], - ['sint64', self.encoder.AppendSInt64NoTag, - 'AppendVarUInt64', None, -1, 1], - ] - - self.assertEqual(len(scalar_no_tag_tests), - len(set(t[0] for t in scalar_no_tag_tests))) - self.assert_(len(scalar_no_tag_tests) >= - len(set(t[1] for t in scalar_no_tag_tests))) - for args in scalar_no_tag_tests: - # For no tag tests, the wire_type is not used, so we put in None. - self.AppendScalarTestHelper(is_tag_test=False, *args) - - def testAppendGroup(self): - field_number = 23 - # Should first append the start-group marker. - self.mock_stream.AppendVarUInt32( - self.PackTag(field_number, wire_format.WIRETYPE_START_GROUP)) - # Should then serialize itself. - self.mock_message.SerializeToString().AndReturn('foo') - self.mock_stream.AppendRawBytes('foo') - # Should finally append the end-group marker. - self.mock_stream.AppendVarUInt32( - self.PackTag(field_number, wire_format.WIRETYPE_END_GROUP)) - - self.mox.ReplayAll() - self.encoder.AppendGroup(field_number, self.mock_message) - self.mox.VerifyAll() - - def testAppendMessage(self): - field_number = 23 - byte_size = 42 - # Should first append the field number and type information. - self.mock_stream.AppendVarUInt32( - self.PackTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)) - # Should then append its length. - self.mock_message.ByteSize().AndReturn(byte_size) - self.mock_stream.AppendVarUInt32(byte_size) - # Should then serialize itself to the encoder. - self.mock_message.SerializeToString().AndReturn('foo') - self.mock_stream.AppendRawBytes('foo') - - self.mox.ReplayAll() - self.encoder.AppendMessage(field_number, self.mock_message) - self.mox.VerifyAll() - - def testAppendMessageSetItem(self): - field_number = 23 - byte_size = 42 - # Should first append the field number and type information. - self.mock_stream.AppendVarUInt32( - self.PackTag(1, wire_format.WIRETYPE_START_GROUP)) - self.mock_stream.AppendVarUInt32( - self.PackTag(2, wire_format.WIRETYPE_VARINT)) - self.mock_stream.AppendVarint32(field_number) - self.mock_stream.AppendVarUInt32( - self.PackTag(3, wire_format.WIRETYPE_LENGTH_DELIMITED)) - # Should then append its length. - self.mock_message.ByteSize().AndReturn(byte_size) - self.mock_stream.AppendVarUInt32(byte_size) - # Should then serialize itself to the encoder. - self.mock_message.SerializeToString().AndReturn('foo') - self.mock_stream.AppendRawBytes('foo') - self.mock_stream.AppendVarUInt32( - self.PackTag(1, wire_format.WIRETYPE_END_GROUP)) - - self.mox.ReplayAll() - self.encoder.AppendMessageSetItem(field_number, self.mock_message) - self.mox.VerifyAll() - - def testAppendSFixed(self): - # Most of our bounds-checking is done in output_stream.py, - # but encoder.py is responsible for transforming signed - # fixed-width integers into unsigned ones, so we test here - # to ensure that we're not losing any entropy when we do - # that conversion. - field_number = 10 - self.assertRaises(message.EncodeError, self.encoder.AppendSFixed32, - 10, wire_format.UINT32_MAX + 1) - self.assertRaises(message.EncodeError, self.encoder.AppendSFixed32, - 10, -(1 << 32)) - self.assertRaises(message.EncodeError, self.encoder.AppendSFixed64, - 10, wire_format.UINT64_MAX + 1) - self.assertRaises(message.EncodeError, self.encoder.AppendSFixed64, - 10, -(1 << 64)) - - -if __name__ == '__main__': - unittest.main() diff --git a/python/google/protobuf/internal/generator_test.py b/python/google/protobuf/internal/generator_test.py index 11fcfa0..78360b5 100755 --- a/python/google/protobuf/internal/generator_test.py +++ b/python/google/protobuf/internal/generator_test.py @@ -35,15 +35,20 @@ # indirect testing of the protocol compiler output. """Unittest that directly tests the output of the pure-Python protocol -compiler. See //net/proto2/internal/reflection_test.py for a test which +compiler. See //google/protobuf/reflection_test.py for a test which further ensures that we can use Python protocol message objects as we expect. """ __author__ = 'robinson@google.com (Will Robinson)' import unittest +from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_mset_pb2 from google.protobuf import unittest_pb2 +from google.protobuf import unittest_no_generic_services_pb2 + + +MAX_EXTENSION = 536870912 class GeneratorTest(unittest.TestCase): @@ -71,6 +76,46 @@ class GeneratorTest(unittest.TestCase): self.assertEqual(3, proto.BAZ) self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ) + def testExtremeDefaultValues(self): + message = unittest_pb2.TestExtremeDefaultValues() + + # Python pre-2.6 does not have isinf() or isnan() functions, so we have + # to provide our own. + def isnan(val): + # NaN is never equal to itself. + return val != val + def isinf(val): + # Infinity times zero equals NaN. + return not isnan(val) and isnan(val * 0) + + self.assertTrue(isinf(message.inf_double)) + self.assertTrue(message.inf_double > 0) + self.assertTrue(isinf(message.neg_inf_double)) + self.assertTrue(message.neg_inf_double < 0) + self.assertTrue(isnan(message.nan_double)) + + self.assertTrue(isinf(message.inf_float)) + self.assertTrue(message.inf_float > 0) + self.assertTrue(isinf(message.neg_inf_float)) + self.assertTrue(message.neg_inf_float < 0) + self.assertTrue(isnan(message.nan_float)) + + def testHasDefaultValues(self): + desc = unittest_pb2.TestAllTypes.DESCRIPTOR + + expected_has_default_by_name = { + 'optional_int32': False, + 'repeated_int32': False, + 'optional_nested_message': False, + 'default_int32': True, + } + + has_default_by_name = dict( + [(f.name, f.has_default_value) + for f in desc.fields + if f.name in expected_has_default_by_name]) + self.assertEqual(expected_has_default_by_name, has_default_by_name) + def testContainingTypeBehaviorForExtensions(self): self.assertEqual(unittest_pb2.optional_int32_extension.containing_type, unittest_pb2.TestAllExtensions.DESCRIPTOR) @@ -95,6 +140,81 @@ class GeneratorTest(unittest.TestCase): proto = unittest_mset_pb2.TestMessageSet() self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format) + def testNestedTypes(self): + self.assertEquals( + set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types), + set([ + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR, + unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR, + unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR, + ])) + self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, []) + self.assertEqual( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, []) + + def testContainingType(self): + self.assertTrue( + unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None) + self.assertTrue( + unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None) + self.assertEqual( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + self.assertEqual( + unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + self.assertEqual( + unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + + def testContainingTypeInEnumDescriptor(self): + self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None) + self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type, + unittest_pb2.TestAllTypes.DESCRIPTOR) + + def testPackage(self): + self.assertEqual( + unittest_pb2.TestAllTypes.DESCRIPTOR.file.package, + 'protobuf_unittest') + desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR + self.assertEqual(desc.file.package, 'protobuf_unittest') + self.assertEqual( + unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package, + 'protobuf_unittest_import') + + self.assertEqual( + unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest') + self.assertEqual( + unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package, + 'protobuf_unittest') + self.assertEqual( + unittest_import_pb2._IMPORTENUM.file.package, + 'protobuf_unittest_import') + + def testExtensionRange(self): + self.assertEqual( + unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, []) + self.assertEqual( + unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges, + [(1, MAX_EXTENSION)]) + self.assertEqual( + unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges, + [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)]) + + def testFileDescriptor(self): + self.assertEqual(unittest_pb2.DESCRIPTOR.name, + 'google/protobuf/unittest.proto') + self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest') + self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None) + + def testNoGenericServices(self): + # unittest_no_generic_services.proto should contain defs for everything + # except services. + self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage")) + self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO")) + self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension")) + self.assertFalse(hasattr(unittest_no_generic_services_pb2, "TestService")) + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/input_stream.py b/python/google/protobuf/internal/input_stream.py deleted file mode 100755 index 7bda17e..0000000 --- a/python/google/protobuf/internal/input_stream.py +++ /dev/null @@ -1,338 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# http://code.google.com/p/protobuf/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""InputStream is the primitive interface for reading bits from the wire. - -All protocol buffer deserialization can be expressed in terms of -the InputStream primitives provided here. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import array -import struct -from google.protobuf import message -from google.protobuf.internal import wire_format - - -# Note that much of this code is ported from //net/proto/ProtocolBuffer, and -# that the interface is strongly inspired by CodedInputStream from the C++ -# proto2 implementation. - - -class InputStreamBuffer(object): - - """Contains all logic for reading bits, and dealing with stream position. - - If an InputStream method ever raises an exception, the stream is left - in an indeterminate state and is not safe for further use. - """ - - def __init__(self, s): - # What we really want is something like array('B', s), where elements we - # read from the array are already given to us as one-byte integers. BUT - # using array() instead of buffer() would force full string copies to result - # from each GetSubBuffer() call. - # - # So, if the N serialized bytes of a single protocol buffer object are - # split evenly between 2 child messages, and so on recursively, using - # array('B', s) instead of buffer() would incur an additional N*logN bytes - # copied during deserialization. - # - # The higher constant overhead of having to ord() for every byte we read - # from the buffer in _ReadVarintHelper() could definitely lead to worse - # performance in many real-world scenarios, even if the asymptotic - # complexity is better. However, our real answer is that the mythical - # Python/C extension module output mode for the protocol compiler will - # be blazing-fast and will eliminate most use of this class anyway. - self._buffer = buffer(s) - self._pos = 0 - - def EndOfStream(self): - """Returns true iff we're at the end of the stream. - If this returns true, then a call to any other InputStream method - will raise an exception. - """ - return self._pos >= len(self._buffer) - - def Position(self): - """Returns the current position in the stream, or equivalently, the - number of bytes read so far. - """ - return self._pos - - def GetSubBuffer(self, size=None): - """Returns a sequence-like object that represents a portion of our - underlying sequence. - - Position 0 in the returned object corresponds to self.Position() - in this stream. - - If size is specified, then the returned object ends after the - next "size" bytes in this stream. If size is not specified, - then the returned object ends at the end of this stream. - - We guarantee that the returned object R supports the Python buffer - interface (and thus that the call buffer(R) will work). - - Note that the returned buffer is read-only. - - The intended use for this method is for nested-message and nested-group - deserialization, where we want to make a recursive MergeFromString() - call on the portion of the original sequence that contains the serialized - nested message. (And we'd like to do so without making unnecessary string - copies). - - REQUIRES: size is nonnegative. - """ - # Note that buffer() doesn't perform any actual string copy. - if size is None: - return buffer(self._buffer, self._pos) - else: - if size < 0: - raise message.DecodeError('Negative size %d' % size) - return buffer(self._buffer, self._pos, size) - - def SkipBytes(self, num_bytes): - """Skip num_bytes bytes ahead, or go to the end of the stream, whichever - comes first. - - REQUIRES: num_bytes is nonnegative. - """ - if num_bytes < 0: - raise message.DecodeError('Negative num_bytes %d' % num_bytes) - self._pos += num_bytes - self._pos = min(self._pos, len(self._buffer)) - - def ReadBytes(self, size): - """Reads up to 'size' bytes from the stream, stopping early - only if we reach the end of the stream. Returns the bytes read - as a string. - """ - if size < 0: - raise message.DecodeError('Negative size %d' % size) - s = (self._buffer[self._pos : self._pos + size]) - self._pos += len(s) # Only advance by the number of bytes actually read. - return s - - def ReadLittleEndian32(self): - """Interprets the next 4 bytes of the stream as a little-endian - encoded, unsiged 32-bit integer, and returns that integer. - """ - try: - i = struct.unpack(wire_format.FORMAT_UINT32_LITTLE_ENDIAN, - self._buffer[self._pos : self._pos + 4]) - self._pos += 4 - return i[0] # unpack() result is a 1-element tuple. - except struct.error, e: - raise message.DecodeError(e) - - def ReadLittleEndian64(self): - """Interprets the next 8 bytes of the stream as a little-endian - encoded, unsiged 64-bit integer, and returns that integer. - """ - try: - i = struct.unpack(wire_format.FORMAT_UINT64_LITTLE_ENDIAN, - self._buffer[self._pos : self._pos + 8]) - self._pos += 8 - return i[0] # unpack() result is a 1-element tuple. - except struct.error, e: - raise message.DecodeError(e) - - def ReadVarint32(self): - """Reads a varint from the stream, interprets this varint - as a signed, 32-bit integer, and returns the integer. - """ - i = self.ReadVarint64() - if not wire_format.INT32_MIN <= i <= wire_format.INT32_MAX: - raise message.DecodeError('Value out of range for int32: %d' % i) - return int(i) - - def ReadVarUInt32(self): - """Reads a varint from the stream, interprets this varint - as an unsigned, 32-bit integer, and returns the integer. - """ - i = self.ReadVarUInt64() - if i > wire_format.UINT32_MAX: - raise message.DecodeError('Value out of range for uint32: %d' % i) - return i - - def ReadVarint64(self): - """Reads a varint from the stream, interprets this varint - as a signed, 64-bit integer, and returns the integer. - """ - i = self.ReadVarUInt64() - if i > wire_format.INT64_MAX: - i -= (1 << 64) - return i - - def ReadVarUInt64(self): - """Reads a varint from the stream, interprets this varint - as an unsigned, 64-bit integer, and returns the integer. - """ - i = self._ReadVarintHelper() - if not 0 <= i <= wire_format.UINT64_MAX: - raise message.DecodeError('Value out of range for uint64: %d' % i) - return i - - def _ReadVarintHelper(self): - """Helper for the various varint-reading methods above. - Reads an unsigned, varint-encoded integer from the stream and - returns this integer. - - Does no bounds checking except to ensure that we read at most as many bytes - as could possibly be present in a varint-encoded 64-bit number. - """ - result = 0 - shift = 0 - while 1: - if shift >= 64: - raise message.DecodeError('Too many bytes when decoding varint.') - try: - b = ord(self._buffer[self._pos]) - except IndexError: - raise message.DecodeError('Truncated varint.') - self._pos += 1 - result |= ((b & 0x7f) << shift) - shift += 7 - if not (b & 0x80): - return result - - -class InputStreamArray(object): - - """Contains all logic for reading bits, and dealing with stream position. - - If an InputStream method ever raises an exception, the stream is left - in an indeterminate state and is not safe for further use. - - This alternative to InputStreamBuffer is used in environments where buffer() - is unavailble, such as Google App Engine. - """ - - def __init__(self, s): - self._buffer = array.array('B', s) - self._pos = 0 - - def EndOfStream(self): - return self._pos >= len(self._buffer) - - def Position(self): - return self._pos - - def GetSubBuffer(self, size=None): - if size is None: - return self._buffer[self._pos : ].tostring() - else: - if size < 0: - raise message.DecodeError('Negative size %d' % size) - return self._buffer[self._pos : self._pos + size].tostring() - - def SkipBytes(self, num_bytes): - if num_bytes < 0: - raise message.DecodeError('Negative num_bytes %d' % num_bytes) - self._pos += num_bytes - self._pos = min(self._pos, len(self._buffer)) - - def ReadBytes(self, size): - if size < 0: - raise message.DecodeError('Negative size %d' % size) - s = self._buffer[self._pos : self._pos + size].tostring() - self._pos += len(s) # Only advance by the number of bytes actually read. - return s - - def ReadLittleEndian32(self): - try: - i = struct.unpack(wire_format.FORMAT_UINT32_LITTLE_ENDIAN, - self._buffer[self._pos : self._pos + 4]) - self._pos += 4 - return i[0] # unpack() result is a 1-element tuple. - except struct.error, e: - raise message.DecodeError(e) - - def ReadLittleEndian64(self): - try: - i = struct.unpack(wire_format.FORMAT_UINT64_LITTLE_ENDIAN, - self._buffer[self._pos : self._pos + 8]) - self._pos += 8 - return i[0] # unpack() result is a 1-element tuple. - except struct.error, e: - raise message.DecodeError(e) - - def ReadVarint32(self): - i = self.ReadVarint64() - if not wire_format.INT32_MIN <= i <= wire_format.INT32_MAX: - raise message.DecodeError('Value out of range for int32: %d' % i) - return int(i) - - def ReadVarUInt32(self): - i = self.ReadVarUInt64() - if i > wire_format.UINT32_MAX: - raise message.DecodeError('Value out of range for uint32: %d' % i) - return i - - def ReadVarint64(self): - i = self.ReadVarUInt64() - if i > wire_format.INT64_MAX: - i -= (1 << 64) - return i - - def ReadVarUInt64(self): - i = self._ReadVarintHelper() - if not 0 <= i <= wire_format.UINT64_MAX: - raise message.DecodeError('Value out of range for uint64: %d' % i) - return i - - def _ReadVarintHelper(self): - result = 0 - shift = 0 - while 1: - if shift >= 64: - raise message.DecodeError('Too many bytes when decoding varint.') - try: - b = self._buffer[self._pos] - except IndexError: - raise message.DecodeError('Truncated varint.') - self._pos += 1 - result |= ((b & 0x7f) << shift) - shift += 7 - if not (b & 0x80): - return result - - -try: - buffer('') - InputStream = InputStreamBuffer -except NotImplementedError: - # Google App Engine: dev_appserver.py - InputStream = InputStreamArray -except RuntimeError: - # Google App Engine: production - InputStream = InputStreamArray diff --git a/python/google/protobuf/internal/input_stream_test.py b/python/google/protobuf/internal/input_stream_test.py deleted file mode 100755 index ecec7f7..0000000 --- a/python/google/protobuf/internal/input_stream_test.py +++ /dev/null @@ -1,314 +0,0 @@ -#! /usr/bin/python -# -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# http://code.google.com/p/protobuf/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Test for google.protobuf.internal.input_stream.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import unittest -from google.protobuf import message -from google.protobuf.internal import wire_format -from google.protobuf.internal import input_stream - - -class InputStreamBufferTest(unittest.TestCase): - - def setUp(self): - self.__original_input_stream = input_stream.InputStream - input_stream.InputStream = input_stream.InputStreamBuffer - - def tearDown(self): - input_stream.InputStream = self.__original_input_stream - - def testEndOfStream(self): - stream = input_stream.InputStream('abcd') - self.assertFalse(stream.EndOfStream()) - self.assertEqual('abcd', stream.ReadBytes(10)) - self.assertTrue(stream.EndOfStream()) - - def testPosition(self): - stream = input_stream.InputStream('abcd') - self.assertEqual(0, stream.Position()) - self.assertEqual(0, stream.Position()) # No side-effects. - stream.ReadBytes(1) - self.assertEqual(1, stream.Position()) - stream.ReadBytes(1) - self.assertEqual(2, stream.Position()) - stream.ReadBytes(10) - self.assertEqual(4, stream.Position()) # Can't go past end of stream. - - def testGetSubBuffer(self): - stream = input_stream.InputStream('abcd') - # Try leaving out the size. - self.assertEqual('abcd', str(stream.GetSubBuffer())) - stream.SkipBytes(1) - # GetSubBuffer() always starts at current size. - self.assertEqual('bcd', str(stream.GetSubBuffer())) - # Try 0-size. - self.assertEqual('', str(stream.GetSubBuffer(0))) - # Negative sizes should raise an error. - self.assertRaises(message.DecodeError, stream.GetSubBuffer, -1) - # Positive sizes should work as expected. - self.assertEqual('b', str(stream.GetSubBuffer(1))) - self.assertEqual('bc', str(stream.GetSubBuffer(2))) - # Sizes longer than remaining bytes in the buffer should - # return the whole remaining buffer. - self.assertEqual('bcd', str(stream.GetSubBuffer(1000))) - - def testSkipBytes(self): - stream = input_stream.InputStream('') - # Skipping bytes when at the end of stream - # should have no effect. - stream.SkipBytes(0) - stream.SkipBytes(1) - stream.SkipBytes(2) - self.assertTrue(stream.EndOfStream()) - self.assertEqual(0, stream.Position()) - - # Try skipping within a stream. - stream = input_stream.InputStream('abcd') - self.assertEqual(0, stream.Position()) - stream.SkipBytes(1) - self.assertEqual(1, stream.Position()) - stream.SkipBytes(10) # Can't skip past the end. - self.assertEqual(4, stream.Position()) - - # Ensure that a negative skip raises an exception. - stream = input_stream.InputStream('abcd') - stream.SkipBytes(1) - self.assertRaises(message.DecodeError, stream.SkipBytes, -1) - - def testReadBytes(self): - s = 'abcd' - # Also test going past the total stream length. - for i in range(len(s) + 10): - stream = input_stream.InputStream(s) - self.assertEqual(s[:i], stream.ReadBytes(i)) - self.assertEqual(min(i, len(s)), stream.Position()) - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadBytes, -1) - - def EnsureFailureOnEmptyStream(self, input_stream_method): - """Helper for integer-parsing tests below. - Ensures that the given InputStream method raises a DecodeError - if called on a stream with no bytes remaining. - """ - stream = input_stream.InputStream('') - self.assertRaises(message.DecodeError, input_stream_method, stream) - - def testReadLittleEndian32(self): - self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadLittleEndian32) - s = '' - # Read 0. - s += '\x00\x00\x00\x00' - # Read 1. - s += '\x01\x00\x00\x00' - # Read a bunch of different bytes. - s += '\x01\x02\x03\x04' - # Read max unsigned 32-bit int. - s += '\xff\xff\xff\xff' - # Try a read with fewer than 4 bytes left in the stream. - s += '\x00\x00\x00' - stream = input_stream.InputStream(s) - self.assertEqual(0, stream.ReadLittleEndian32()) - self.assertEqual(4, stream.Position()) - self.assertEqual(1, stream.ReadLittleEndian32()) - self.assertEqual(8, stream.Position()) - self.assertEqual(0x04030201, stream.ReadLittleEndian32()) - self.assertEqual(12, stream.Position()) - self.assertEqual(wire_format.UINT32_MAX, stream.ReadLittleEndian32()) - self.assertEqual(16, stream.Position()) - self.assertRaises(message.DecodeError, stream.ReadLittleEndian32) - - def testReadLittleEndian64(self): - self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadLittleEndian64) - s = '' - # Read 0. - s += '\x00\x00\x00\x00\x00\x00\x00\x00' - # Read 1. - s += '\x01\x00\x00\x00\x00\x00\x00\x00' - # Read a bunch of different bytes. - s += '\x01\x02\x03\x04\x05\x06\x07\x08' - # Read max unsigned 64-bit int. - s += '\xff\xff\xff\xff\xff\xff\xff\xff' - # Try a read with fewer than 8 bytes left in the stream. - s += '\x00\x00\x00' - stream = input_stream.InputStream(s) - self.assertEqual(0, stream.ReadLittleEndian64()) - self.assertEqual(8, stream.Position()) - self.assertEqual(1, stream.ReadLittleEndian64()) - self.assertEqual(16, stream.Position()) - self.assertEqual(0x0807060504030201, stream.ReadLittleEndian64()) - self.assertEqual(24, stream.Position()) - self.assertEqual(wire_format.UINT64_MAX, stream.ReadLittleEndian64()) - self.assertEqual(32, stream.Position()) - self.assertRaises(message.DecodeError, stream.ReadLittleEndian64) - - def ReadVarintSuccessTestHelper(self, varints_and_ints, read_method): - """Helper for tests below that test successful reads of various varints. - - Args: - varints_and_ints: Iterable of (str, integer) pairs, where the string - gives the wire encoding and the integer gives the value we expect - to be returned by the read_method upon encountering this string. - read_method: Unbound InputStream method that is capable of reading - the encoded strings provided in the first elements of varints_and_ints. - """ - s = ''.join(s for s, i in varints_and_ints) - stream = input_stream.InputStream(s) - expected_pos = 0 - self.assertEqual(expected_pos, stream.Position()) - for s, expected_int in varints_and_ints: - self.assertEqual(expected_int, read_method(stream)) - expected_pos += len(s) - self.assertEqual(expected_pos, stream.Position()) - - def testReadVarint32Success(self): - varints_and_ints = [ - ('\x00', 0), - ('\x01', 1), - ('\x7f', 127), - ('\x80\x01', 128), - ('\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01', -1), - ('\xff\xff\xff\xff\x07', wire_format.INT32_MAX), - ('\x80\x80\x80\x80\xf8\xff\xff\xff\xff\x01', wire_format.INT32_MIN), - ] - self.ReadVarintSuccessTestHelper(varints_and_ints, - input_stream.InputStream.ReadVarint32) - - def testReadVarint32Failure(self): - self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarint32) - - # Try and fail to read INT32_MAX + 1. - s = '\x80\x80\x80\x80\x08' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarint32) - - # Try and fail to read INT32_MIN - 1. - s = '\xfe\xff\xff\xff\xf7\xff\xff\xff\xff\x01' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarint32) - - # Try and fail to read something that looks like - # a varint with more than 10 bytes. - s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarint32) - - def testReadVarUInt32Success(self): - varints_and_ints = [ - ('\x00', 0), - ('\x01', 1), - ('\x7f', 127), - ('\x80\x01', 128), - ('\xff\xff\xff\xff\x0f', wire_format.UINT32_MAX), - ] - self.ReadVarintSuccessTestHelper(varints_and_ints, - input_stream.InputStream.ReadVarUInt32) - - def testReadVarUInt32Failure(self): - self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarUInt32) - # Try and fail to read UINT32_MAX + 1 - s = '\x80\x80\x80\x80\x10' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarUInt32) - - # Try and fail to read something that looks like - # a varint with more than 10 bytes. - s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarUInt32) - - def testReadVarint64Success(self): - varints_and_ints = [ - ('\x00', 0), - ('\x01', 1), - ('\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01', -1), - ('\x7f', 127), - ('\x80\x01', 128), - ('\xff\xff\xff\xff\xff\xff\xff\xff\x7f', wire_format.INT64_MAX), - ('\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01', wire_format.INT64_MIN), - ] - self.ReadVarintSuccessTestHelper(varints_and_ints, - input_stream.InputStream.ReadVarint64) - - def testReadVarint64Failure(self): - self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarint64) - # Try and fail to read something with the mythical 64th bit set. - s = '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarint64) - - # Try and fail to read something that looks like - # a varint with more than 10 bytes. - s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarint64) - - def testReadVarUInt64Success(self): - varints_and_ints = [ - ('\x00', 0), - ('\x01', 1), - ('\x7f', 127), - ('\x80\x01', 128), - ('\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01', 1 << 63), - ] - self.ReadVarintSuccessTestHelper(varints_and_ints, - input_stream.InputStream.ReadVarUInt64) - - def testReadVarUInt64Failure(self): - self.EnsureFailureOnEmptyStream(input_stream.InputStream.ReadVarUInt64) - # Try and fail to read something with the mythical 64th bit set. - s = '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarUInt64) - - # Try and fail to read something that looks like - # a varint with more than 10 bytes. - s = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' - stream = input_stream.InputStream(s) - self.assertRaises(message.DecodeError, stream.ReadVarUInt64) - - -class InputStreamArrayTest(InputStreamBufferTest): - - def setUp(self): - # Test InputStreamArray against the same tests in InputStreamBuffer - self.__original_input_stream = input_stream.InputStream - input_stream.InputStream = input_stream.InputStreamArray - - def tearDown(self): - input_stream.InputStream = self.__original_input_stream - - -if __name__ == '__main__': - unittest.main() diff --git a/python/google/protobuf/internal/message_listener.py b/python/google/protobuf/internal/message_listener.py index 4397895..1080234 100755 --- a/python/google/protobuf/internal/message_listener.py +++ b/python/google/protobuf/internal/message_listener.py @@ -39,22 +39,34 @@ __author__ = 'robinson@google.com (Will Robinson)' class MessageListener(object): - """Listens for transitions to nonempty and for invalidations of cached - byte sizes. Meant to be registered via Message._SetListener(). + """Listens for modifications made to a message. Meant to be registered via + Message._SetListener(). + + Attributes: + dirty: If True, then calling Modified() would be a no-op. This can be + used to avoid these calls entirely in the common case. """ - def TransitionToNonempty(self): - """Called the *first* time that this message becomes nonempty. - Implementations are free (but not required) to call this method multiple - times after the message has become nonempty. - """ - raise NotImplementedError + def Modified(self): + """Called every time the message is modified in such a way that the parent + message may need to be updated. This currently means either: + (a) The message was modified for the first time, so the parent message + should henceforth mark the message as present. + (b) The message's cached byte size became dirty -- i.e. the message was + modified for the first time after a previous call to ByteSize(). + Therefore the parent should also mark its byte size as dirty. + Note that (a) implies (b), since new objects start out with a client cached + size (zero). However, we document (a) explicitly because it is important. + + Modified() will *only* be called in response to one of these two events -- + not every time the sub-message is modified. - def ByteSizeDirty(self): - """Called *every* time the cached byte size value - for this object is invalidated (transitions from being - "clean" to "dirty"). + Note that if the listener's |dirty| attribute is true, then calling + Modified at the moment would be a no-op, so it can be skipped. Performance- + sensitive callers should check this attribute directly before calling since + it will be true most of the time. """ + raise NotImplementedError @@ -62,8 +74,5 @@ class NullMessageListener(object): """No-op MessageListener implementation.""" - def TransitionToNonempty(self): - pass - - def ByteSizeDirty(self): + def Modified(self): pass diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index df344cf..73a9a3a 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -30,7 +30,16 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Tests python protocol buffers against the golden message.""" +"""Tests python protocol buffers against the golden message. + +Note that the golden messages exercise every known field type, thus this +test ends up exercising and verifying nearly all of the parsing and +serialization code in the whole library. + +TODO(kenton): Merge with wire_format_test? It doesn't make a whole lot of +sense to call this a test of the "message" module, which only declares an +abstract interface. +""" __author__ = 'gps@google.com (Gregory P. Smith)' @@ -40,14 +49,41 @@ from google.protobuf import unittest_pb2 from google.protobuf.internal import test_util -class MessageTest(test_util.GoldenMessageTestCase): +class MessageTest(unittest.TestCase): def testGoldenMessage(self): golden_data = test_util.GoldenFile('golden_message').read() golden_message = unittest_pb2.TestAllTypes() golden_message.ParseFromString(golden_data) - self.ExpectAllFieldsSet(golden_message) + test_util.ExpectAllFieldsSet(self, golden_message) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testGoldenExtensions(self): + golden_data = test_util.GoldenFile('golden_message').read() + golden_message = unittest_pb2.TestAllExtensions() + golden_message.ParseFromString(golden_data) + all_set = unittest_pb2.TestAllExtensions() + test_util.SetAllExtensions(all_set) + self.assertEquals(all_set, golden_message) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testGoldenPackedMessage(self): + golden_data = test_util.GoldenFile('golden_packed_fields_message').read() + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + all_set = unittest_pb2.TestPackedTypes() + test_util.SetAllPackedFields(all_set) + self.assertEquals(all_set, golden_message) + self.assertTrue(all_set.SerializeToString() == golden_data) + def testGoldenPackedExtensions(self): + golden_data = test_util.GoldenFile('golden_packed_fields_message').read() + golden_message = unittest_pb2.TestPackedExtensions() + golden_message.ParseFromString(golden_data) + all_set = unittest_pb2.TestPackedExtensions() + test_util.SetAllPackedExtensions(all_set) + self.assertEquals(all_set, golden_message) + self.assertTrue(all_set.SerializeToString() == golden_data) if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/output_stream.py b/python/google/protobuf/internal/output_stream.py deleted file mode 100755 index 6c2d6f6..0000000 --- a/python/google/protobuf/internal/output_stream.py +++ /dev/null @@ -1,125 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# http://code.google.com/p/protobuf/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""OutputStream is the primitive interface for sticking bits on the wire. - -All protocol buffer serialization can be expressed in terms of -the OutputStream primitives provided here. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import array -import struct -from google.protobuf import message -from google.protobuf.internal import wire_format - - - -# Note that much of this code is ported from //net/proto/ProtocolBuffer, and -# that the interface is strongly inspired by CodedOutputStream from the C++ -# proto2 implementation. - - -class OutputStream(object): - - """Contains all logic for writing bits, and ToString() to get the result.""" - - def __init__(self): - self._buffer = array.array('B') - - def AppendRawBytes(self, raw_bytes): - """Appends raw_bytes to our internal buffer.""" - self._buffer.fromstring(raw_bytes) - - def AppendLittleEndian32(self, unsigned_value): - """Appends an unsigned 32-bit integer to the internal buffer, - in little-endian byte order. - """ - if not 0 <= unsigned_value <= wire_format.UINT32_MAX: - raise message.EncodeError( - 'Unsigned 32-bit out of range: %d' % unsigned_value) - self._buffer.fromstring(struct.pack( - wire_format.FORMAT_UINT32_LITTLE_ENDIAN, unsigned_value)) - - def AppendLittleEndian64(self, unsigned_value): - """Appends an unsigned 64-bit integer to the internal buffer, - in little-endian byte order. - """ - if not 0 <= unsigned_value <= wire_format.UINT64_MAX: - raise message.EncodeError( - 'Unsigned 64-bit out of range: %d' % unsigned_value) - self._buffer.fromstring(struct.pack( - wire_format.FORMAT_UINT64_LITTLE_ENDIAN, unsigned_value)) - - def AppendVarint32(self, value): - """Appends a signed 32-bit integer to the internal buffer, - encoded as a varint. (Note that a negative varint32 will - always require 10 bytes of space.) - """ - if not wire_format.INT32_MIN <= value <= wire_format.INT32_MAX: - raise message.EncodeError('Value out of range: %d' % value) - self.AppendVarint64(value) - - def AppendVarUInt32(self, value): - """Appends an unsigned 32-bit integer to the internal buffer, - encoded as a varint. - """ - if not 0 <= value <= wire_format.UINT32_MAX: - raise message.EncodeError('Value out of range: %d' % value) - self.AppendVarUInt64(value) - - def AppendVarint64(self, value): - """Appends a signed 64-bit integer to the internal buffer, - encoded as a varint. - """ - if not wire_format.INT64_MIN <= value <= wire_format.INT64_MAX: - raise message.EncodeError('Value out of range: %d' % value) - if value < 0: - value += (1 << 64) - self.AppendVarUInt64(value) - - def AppendVarUInt64(self, unsigned_value): - """Appends an unsigned 64-bit integer to the internal buffer, - encoded as a varint. - """ - if not 0 <= unsigned_value <= wire_format.UINT64_MAX: - raise message.EncodeError('Value out of range: %d' % unsigned_value) - while True: - bits = unsigned_value & 0x7f - unsigned_value >>= 7 - if not unsigned_value: - self._buffer.append(bits) - break - self._buffer.append(0x80|bits) - - def ToString(self): - """Returns a string containing the bytes in our internal buffer.""" - return self._buffer.tostring() diff --git a/python/google/protobuf/internal/output_stream_test.py b/python/google/protobuf/internal/output_stream_test.py deleted file mode 100755 index df92eec..0000000 --- a/python/google/protobuf/internal/output_stream_test.py +++ /dev/null @@ -1,178 +0,0 @@ -#! /usr/bin/python -# -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# http://code.google.com/p/protobuf/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Test for google.protobuf.internal.output_stream.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import unittest -from google.protobuf import message -from google.protobuf.internal import output_stream -from google.protobuf.internal import wire_format - - -class OutputStreamTest(unittest.TestCase): - - def setUp(self): - self.stream = output_stream.OutputStream() - - def testAppendRawBytes(self): - # Empty string. - self.stream.AppendRawBytes('') - self.assertEqual('', self.stream.ToString()) - - # Nonempty string. - self.stream.AppendRawBytes('abc') - self.assertEqual('abc', self.stream.ToString()) - - # Ensure that we're actually appending. - self.stream.AppendRawBytes('def') - self.assertEqual('abcdef', self.stream.ToString()) - - def AppendNumericTestHelper(self, append_fn, values_and_strings): - """For each (value, expected_string) pair in values_and_strings, - calls an OutputStream.Append*(value) method on an OutputStream and ensures - that the string written to that stream matches expected_string. - - Args: - append_fn: Unbound OutputStream method that takes an integer or - long value as input. - values_and_strings: Iterable of (value, expected_string) pairs. - """ - for conversion in (int, long): - for value, string in values_and_strings: - stream = output_stream.OutputStream() - expected_string = '' - append_fn(stream, conversion(value)) - expected_string += string - self.assertEqual(expected_string, stream.ToString()) - - def AppendOverflowTestHelper(self, append_fn, value): - """Calls an OutputStream.Append*(value) method and asserts - that the method raises message.EncodeError. - - Args: - append_fn: Unbound OutputStream method that takes an integer or - long value as input. - value: Value to pass to append_fn which should cause an - message.EncodeError. - """ - stream = output_stream.OutputStream() - self.assertRaises(message.EncodeError, append_fn, stream, value) - - def testAppendLittleEndian32(self): - append_fn = output_stream.OutputStream.AppendLittleEndian32 - values_and_expected_strings = [ - (0, '\x00\x00\x00\x00'), - (1, '\x01\x00\x00\x00'), - ((1 << 32) - 1, '\xff\xff\xff\xff'), - ] - self.AppendNumericTestHelper(append_fn, values_and_expected_strings) - - self.AppendOverflowTestHelper(append_fn, 1 << 32) - self.AppendOverflowTestHelper(append_fn, -1) - - def testAppendLittleEndian64(self): - append_fn = output_stream.OutputStream.AppendLittleEndian64 - values_and_expected_strings = [ - (0, '\x00\x00\x00\x00\x00\x00\x00\x00'), - (1, '\x01\x00\x00\x00\x00\x00\x00\x00'), - ((1 << 64) - 1, '\xff\xff\xff\xff\xff\xff\xff\xff'), - ] - self.AppendNumericTestHelper(append_fn, values_and_expected_strings) - - self.AppendOverflowTestHelper(append_fn, 1 << 64) - self.AppendOverflowTestHelper(append_fn, -1) - - def testAppendVarint32(self): - append_fn = output_stream.OutputStream.AppendVarint32 - values_and_expected_strings = [ - (0, '\x00'), - (1, '\x01'), - (127, '\x7f'), - (128, '\x80\x01'), - (-1, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01'), - (wire_format.INT32_MAX, '\xff\xff\xff\xff\x07'), - (wire_format.INT32_MIN, '\x80\x80\x80\x80\xf8\xff\xff\xff\xff\x01'), - ] - self.AppendNumericTestHelper(append_fn, values_and_expected_strings) - - self.AppendOverflowTestHelper(append_fn, wire_format.INT32_MAX + 1) - self.AppendOverflowTestHelper(append_fn, wire_format.INT32_MIN - 1) - - def testAppendVarUInt32(self): - append_fn = output_stream.OutputStream.AppendVarUInt32 - values_and_expected_strings = [ - (0, '\x00'), - (1, '\x01'), - (127, '\x7f'), - (128, '\x80\x01'), - (wire_format.UINT32_MAX, '\xff\xff\xff\xff\x0f'), - ] - self.AppendNumericTestHelper(append_fn, values_and_expected_strings) - - self.AppendOverflowTestHelper(append_fn, -1) - self.AppendOverflowTestHelper(append_fn, wire_format.UINT32_MAX + 1) - - def testAppendVarint64(self): - append_fn = output_stream.OutputStream.AppendVarint64 - values_and_expected_strings = [ - (0, '\x00'), - (1, '\x01'), - (127, '\x7f'), - (128, '\x80\x01'), - (-1, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01'), - (wire_format.INT64_MAX, '\xff\xff\xff\xff\xff\xff\xff\xff\x7f'), - (wire_format.INT64_MIN, '\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01'), - ] - self.AppendNumericTestHelper(append_fn, values_and_expected_strings) - - self.AppendOverflowTestHelper(append_fn, wire_format.INT64_MAX + 1) - self.AppendOverflowTestHelper(append_fn, wire_format.INT64_MIN - 1) - - def testAppendVarUInt64(self): - append_fn = output_stream.OutputStream.AppendVarUInt64 - values_and_expected_strings = [ - (0, '\x00'), - (1, '\x01'), - (127, '\x7f'), - (128, '\x80\x01'), - (wire_format.UINT64_MAX, '\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01'), - ] - self.AppendNumericTestHelper(append_fn, values_and_expected_strings) - - self.AppendOverflowTestHelper(append_fn, -1) - self.AppendOverflowTestHelper(append_fn, wire_format.UINT64_MAX + 1) - - -if __name__ == '__main__': - unittest.main() diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index 8610177..2c9fa30 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -38,6 +38,7 @@ pure-Python protocol compiler. __author__ = 'robinson@google.com (Will Robinson)' import operator +import struct import unittest # TODO(robinson): When we split this test in two, only some of these imports @@ -56,6 +57,51 @@ from google.protobuf.internal import test_util from google.protobuf.internal import decoder +class _MiniDecoder(object): + """Decodes a stream of values from a string. + + Once upon a time we actually had a class called decoder.Decoder. Then we + got rid of it during a redesign that made decoding much, much faster overall. + But a couple tests in this file used it to check that the serialized form of + a message was correct. So, this class implements just the methods that were + used by said tests, so that we don't have to rewrite the tests. + """ + + def __init__(self, bytes): + self._bytes = bytes + self._pos = 0 + + def ReadVarint(self): + result, self._pos = decoder._DecodeVarint(self._bytes, self._pos) + return result + + ReadInt32 = ReadVarint + ReadInt64 = ReadVarint + ReadUInt32 = ReadVarint + ReadUInt64 = ReadVarint + + def ReadSInt64(self): + return wire_format.ZigZagDecode(self.ReadVarint()) + + ReadSInt32 = ReadSInt64 + + def ReadFieldNumberAndWireType(self): + return wire_format.UnpackTag(self.ReadVarint()) + + def ReadFloat(self): + result = struct.unpack("<f", self._bytes[self._pos:self._pos+4])[0] + self._pos += 4 + return result + + def ReadDouble(self): + result = struct.unpack("<d", self._bytes[self._pos:self._pos+8])[0] + self._pos += 8 + return result + + def EndOfStream(self): + return self._pos == len(self._bytes) + + class ReflectionTest(unittest.TestCase): def assertIs(self, values, others): @@ -63,6 +109,97 @@ class ReflectionTest(unittest.TestCase): for i in range(len(values)): self.assertTrue(values[i] is others[i]) + def testScalarConstructor(self): + # Constructor with only scalar types should succeed. + proto = unittest_pb2.TestAllTypes( + optional_int32=24, + optional_double=54.321, + optional_string='optional_string') + + self.assertEqual(24, proto.optional_int32) + self.assertEqual(54.321, proto.optional_double) + self.assertEqual('optional_string', proto.optional_string) + + def testRepeatedScalarConstructor(self): + # Constructor with only repeated scalar types should succeed. + proto = unittest_pb2.TestAllTypes( + repeated_int32=[1, 2, 3, 4], + repeated_double=[1.23, 54.321], + repeated_bool=[True, False, False], + repeated_string=["optional_string"]) + + self.assertEquals([1, 2, 3, 4], list(proto.repeated_int32)) + self.assertEquals([1.23, 54.321], list(proto.repeated_double)) + self.assertEquals([True, False, False], list(proto.repeated_bool)) + self.assertEquals(["optional_string"], list(proto.repeated_string)) + + def testRepeatedCompositeConstructor(self): + # Constructor with only repeated composite types should succeed. + proto = unittest_pb2.TestAllTypes( + repeated_nested_message=[ + unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.FOO), + unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.BAR)], + repeated_foreign_message=[ + unittest_pb2.ForeignMessage(c=-43), + unittest_pb2.ForeignMessage(c=45324), + unittest_pb2.ForeignMessage(c=12)], + repeatedgroup=[ + unittest_pb2.TestAllTypes.RepeatedGroup(), + unittest_pb2.TestAllTypes.RepeatedGroup(a=1), + unittest_pb2.TestAllTypes.RepeatedGroup(a=2)]) + + self.assertEquals( + [unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.FOO), + unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.BAR)], + list(proto.repeated_nested_message)) + self.assertEquals( + [unittest_pb2.ForeignMessage(c=-43), + unittest_pb2.ForeignMessage(c=45324), + unittest_pb2.ForeignMessage(c=12)], + list(proto.repeated_foreign_message)) + self.assertEquals( + [unittest_pb2.TestAllTypes.RepeatedGroup(), + unittest_pb2.TestAllTypes.RepeatedGroup(a=1), + unittest_pb2.TestAllTypes.RepeatedGroup(a=2)], + list(proto.repeatedgroup)) + + def testMixedConstructor(self): + # Constructor with only mixed types should succeed. + proto = unittest_pb2.TestAllTypes( + optional_int32=24, + optional_string='optional_string', + repeated_double=[1.23, 54.321], + repeated_bool=[True, False, False], + repeated_nested_message=[ + unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.FOO), + unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.BAR)], + repeated_foreign_message=[ + unittest_pb2.ForeignMessage(c=-43), + unittest_pb2.ForeignMessage(c=45324), + unittest_pb2.ForeignMessage(c=12)]) + + self.assertEqual(24, proto.optional_int32) + self.assertEqual('optional_string', proto.optional_string) + self.assertEquals([1.23, 54.321], list(proto.repeated_double)) + self.assertEquals([True, False, False], list(proto.repeated_bool)) + self.assertEquals( + [unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.FOO), + unittest_pb2.TestAllTypes.NestedMessage( + bb=unittest_pb2.TestAllTypes.BAR)], + list(proto.repeated_nested_message)) + self.assertEquals( + [unittest_pb2.ForeignMessage(c=-43), + unittest_pb2.ForeignMessage(c=45324), + unittest_pb2.ForeignMessage(c=12)], + list(proto.repeated_foreign_message)) + def testSimpleHasBits(self): # Test a scalar. proto = unittest_pb2.TestAllTypes() @@ -218,12 +355,23 @@ class ReflectionTest(unittest.TestCase): proto.optional_fixed32 = 1 proto.optional_int32 = 5 proto.optional_string = 'foo' + # Access sub-message but don't set it yet. + nested_message = proto.optional_nested_message self.assertEqual( [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 5), (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1), (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo') ], proto.ListFields()) + proto.optional_nested_message.bb = 123 + self.assertEqual( + [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 5), + (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1), + (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo'), + (proto.DESCRIPTOR.fields_by_name['optional_nested_message' ], + nested_message) ], + proto.ListFields()) + def testRepeatedListFields(self): proto = unittest_pb2.TestAllTypes() proto.repeated_fixed32.append(1) @@ -234,6 +382,7 @@ class ReflectionTest(unittest.TestCase): proto.repeated_string.append('baz') proto.repeated_string.extend(str(x) for x in xrange(2)) proto.optional_int32 = 21 + proto.repeated_bool # Access but don't set anything; should not be listed. self.assertEqual( [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 21), (proto.DESCRIPTOR.fields_by_name['repeated_int32' ], [5, 11]), @@ -731,7 +880,6 @@ class ReflectionTest(unittest.TestCase): extendee_proto.ClearExtension(extension) extension_proto.foreign_message_int = 23 - self.assertTrue(not toplevel.HasField('submessage')) self.assertTrue(extension_proto is not extendee_proto.Extensions[extension]) def testExtensionFailureModes(self): @@ -957,57 +1105,75 @@ class ReflectionTest(unittest.TestCase): empty_proto = unittest_pb2.TestAllExtensions() self.assertEquals(proto, empty_proto) + def assertInitialized(self, proto): + self.assertTrue(proto.IsInitialized()) + # Neither method should raise an exception. + proto.SerializeToString() + proto.SerializePartialToString() + + def assertNotInitialized(self, proto): + self.assertFalse(proto.IsInitialized()) + self.assertRaises(message.EncodeError, proto.SerializeToString) + # "Partial" serialization doesn't care if message is uninitialized. + proto.SerializePartialToString() + def testIsInitialized(self): # Trivial cases - all optional fields and extensions. proto = unittest_pb2.TestAllTypes() - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) proto = unittest_pb2.TestAllExtensions() - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) # The case of uninitialized required fields. proto = unittest_pb2.TestRequired() - self.assertFalse(proto.IsInitialized()) + self.assertNotInitialized(proto) proto.a = proto.b = proto.c = 2 - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) # The case of uninitialized submessage. proto = unittest_pb2.TestRequiredForeign() - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) proto.optional_message.a = 1 - self.assertFalse(proto.IsInitialized()) + self.assertNotInitialized(proto) proto.optional_message.b = 0 proto.optional_message.c = 0 - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) # Uninitialized repeated submessage. message1 = proto.repeated_message.add() - self.assertFalse(proto.IsInitialized()) + self.assertNotInitialized(proto) message1.a = message1.b = message1.c = 0 - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) # Uninitialized repeated group in an extension. proto = unittest_pb2.TestAllExtensions() extension = unittest_pb2.TestRequired.multi message1 = proto.Extensions[extension].add() message2 = proto.Extensions[extension].add() - self.assertFalse(proto.IsInitialized()) + self.assertNotInitialized(proto) message1.a = 1 message1.b = 1 message1.c = 1 - self.assertFalse(proto.IsInitialized()) + self.assertNotInitialized(proto) message2.a = 2 message2.b = 2 message2.c = 2 - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) # Uninitialized nonrepeated message in an extension. proto = unittest_pb2.TestAllExtensions() extension = unittest_pb2.TestRequired.single proto.Extensions[extension].a = 1 - self.assertFalse(proto.IsInitialized()) + self.assertNotInitialized(proto) proto.Extensions[extension].b = 2 proto.Extensions[extension].c = 3 - self.assertTrue(proto.IsInitialized()) + self.assertInitialized(proto) + + # Try passing an errors list. + errors = [] + proto = unittest_pb2.TestRequired() + self.assertFalse(proto.IsInitialized(errors)) + self.assertEqual(errors, ['a', 'b', 'c']) def testStringUTF8Encoding(self): proto = unittest_pb2.TestAllTypes() @@ -1079,6 +1245,36 @@ class ReflectionTest(unittest.TestCase): test_utf8_bytes, len(test_utf8_bytes) * '\xff') self.assertRaises(UnicodeDecodeError, message2.MergeFromString, bytes) + def testEmptyNestedMessage(self): + proto = unittest_pb2.TestAllTypes() + proto.optional_nested_message.MergeFrom( + unittest_pb2.TestAllTypes.NestedMessage()) + self.assertTrue(proto.HasField('optional_nested_message')) + + proto = unittest_pb2.TestAllTypes() + proto.optional_nested_message.CopyFrom( + unittest_pb2.TestAllTypes.NestedMessage()) + self.assertTrue(proto.HasField('optional_nested_message')) + + proto = unittest_pb2.TestAllTypes() + proto.optional_nested_message.MergeFromString('') + self.assertTrue(proto.HasField('optional_nested_message')) + + proto = unittest_pb2.TestAllTypes() + proto.optional_nested_message.ParseFromString('') + self.assertTrue(proto.HasField('optional_nested_message')) + + serialized = proto.SerializeToString() + proto2 = unittest_pb2.TestAllTypes() + proto2.MergeFromString(serialized) + self.assertTrue(proto2.HasField('optional_nested_message')) + + def testSetInParent(self): + proto = unittest_pb2.TestAllTypes() + self.assertFalse(proto.HasField('optionalgroup')) + proto.optionalgroup.SetInParent() + self.assertTrue(proto.HasField('optionalgroup')) + # Since we had so many tests for protocol buffer equality, we broke these out # into separate TestCase classes. @@ -1541,6 +1737,47 @@ class SerializationTest(unittest.TestCase): second_proto.MergeFromString(serialized) self.assertEqual(first_proto, second_proto) + def testSerializeNegativeValues(self): + first_proto = unittest_pb2.TestAllTypes() + + first_proto.optional_int32 = -1 + first_proto.optional_int64 = -(2 << 40) + first_proto.optional_sint32 = -3 + first_proto.optional_sint64 = -(4 << 40) + first_proto.optional_sfixed32 = -5 + first_proto.optional_sfixed64 = -(6 << 40) + + second_proto = unittest_pb2.TestAllTypes.FromString( + first_proto.SerializeToString()) + + self.assertEqual(first_proto, second_proto) + + def testParseTruncated(self): + first_proto = unittest_pb2.TestAllTypes() + test_util.SetAllFields(first_proto) + serialized = first_proto.SerializeToString() + + for truncation_point in xrange(len(serialized) + 1): + try: + second_proto = unittest_pb2.TestAllTypes() + unknown_fields = unittest_pb2.TestEmptyMessage() + pos = second_proto._InternalParse(serialized, 0, truncation_point) + # If we didn't raise an error then we read exactly the amount expected. + self.assertEqual(truncation_point, pos) + + # Parsing to unknown fields should not throw if parsing to known fields + # did not. + try: + pos2 = unknown_fields._InternalParse(serialized, 0, truncation_point) + self.assertEqual(truncation_point, pos2) + except message.DecodeError: + self.fail('Parsing unknown fields failed when parsing known fields ' + 'did not.') + except message.DecodeError: + # Parsing unknown fields should also fail. + self.assertRaises(message.DecodeError, unknown_fields._InternalParse, + serialized, 0, truncation_point) + def testCanonicalSerializationOrder(self): proto = more_messages_pb2.OutOfOrderFields() # These are also their tag numbers. Even though we're setting these in @@ -1553,7 +1790,7 @@ class SerializationTest(unittest.TestCase): proto.optional_int32 = 1 serialized = proto.SerializeToString() self.assertEqual(proto.ByteSize(), len(serialized)) - d = decoder.Decoder(serialized) + d = _MiniDecoder(serialized) ReadTag = d.ReadFieldNumberAndWireType self.assertEqual((1, wire_format.WIRETYPE_VARINT), ReadTag()) self.assertEqual(1, d.ReadInt32()) @@ -1709,7 +1946,7 @@ class SerializationTest(unittest.TestCase): self._CheckRaises( message.EncodeError, proto.SerializeToString, - 'Required field protobuf_unittest.TestRequired.a is not set.') + 'Message is missing required fields: a,b,c') # Shouldn't raise exceptions. partial = proto.SerializePartialToString() @@ -1717,7 +1954,7 @@ class SerializationTest(unittest.TestCase): self._CheckRaises( message.EncodeError, proto.SerializeToString, - 'Required field protobuf_unittest.TestRequired.b is not set.') + 'Message is missing required fields: b,c') # Shouldn't raise exceptions. partial = proto.SerializePartialToString() @@ -1725,7 +1962,7 @@ class SerializationTest(unittest.TestCase): self._CheckRaises( message.EncodeError, proto.SerializeToString, - 'Required field protobuf_unittest.TestRequired.c is not set.') + 'Message is missing required fields: c') # Shouldn't raise exceptions. partial = proto.SerializePartialToString() @@ -1744,6 +1981,38 @@ class SerializationTest(unittest.TestCase): self.assertEqual(2, proto2.b) self.assertEqual(3, proto2.c) + def testSerializeUninitializedSubMessage(self): + proto = unittest_pb2.TestRequiredForeign() + + # Sub-message doesn't exist yet, so this succeeds. + proto.SerializeToString() + + proto.optional_message.a = 1 + self._CheckRaises( + message.EncodeError, + proto.SerializeToString, + 'Message is missing required fields: ' + 'optional_message.b,optional_message.c') + + proto.optional_message.b = 2 + proto.optional_message.c = 3 + proto.SerializeToString() + + proto.repeated_message.add().a = 1 + proto.repeated_message.add().b = 2 + self._CheckRaises( + message.EncodeError, + proto.SerializeToString, + 'Message is missing required fields: ' + 'repeated_message[0].b,repeated_message[0].c,' + 'repeated_message[1].a,repeated_message[1].c') + + proto.repeated_message[0].b = 2 + proto.repeated_message[0].c = 3 + proto.repeated_message[1].a = 1 + proto.repeated_message[1].c = 3 + proto.SerializeToString() + def testSerializeAllPackedFields(self): first_proto = unittest_pb2.TestPackedTypes() second_proto = unittest_pb2.TestPackedTypes() @@ -1786,7 +2055,7 @@ class SerializationTest(unittest.TestCase): proto.packed_float.append(2.0) # 4 bytes, will be before double serialized = proto.SerializeToString() self.assertEqual(proto.ByteSize(), len(serialized)) - d = decoder.Decoder(serialized) + d = _MiniDecoder(serialized) ReadTag = d.ReadFieldNumberAndWireType self.assertEqual((90, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag()) self.assertEqual(1+1+1+2, d.ReadInt32()) @@ -1803,6 +2072,24 @@ class SerializationTest(unittest.TestCase): self.assertEqual(1000.0, d.ReadDouble()) self.assertTrue(d.EndOfStream()) + def testParsePackedFromUnpacked(self): + unpacked = unittest_pb2.TestUnpackedTypes() + test_util.SetAllUnpackedFields(unpacked) + packed = unittest_pb2.TestPackedTypes() + packed.MergeFromString(unpacked.SerializeToString()) + expected = unittest_pb2.TestPackedTypes() + test_util.SetAllPackedFields(expected) + self.assertEqual(expected, packed) + + def testParseUnpackedFromPacked(self): + packed = unittest_pb2.TestPackedTypes() + test_util.SetAllPackedFields(packed) + unpacked = unittest_pb2.TestUnpackedTypes() + unpacked.MergeFromString(packed.SerializeToString()) + expected = unittest_pb2.TestUnpackedTypes() + test_util.SetAllUnpackedFields(expected) + self.assertEqual(expected, unpacked) + def testFieldNumbers(self): proto = unittest_pb2.TestAllTypes() self.assertEqual(unittest_pb2.TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1) @@ -1944,33 +2231,6 @@ class OptionsTest(unittest.TestCase): field_descriptor.label) -class UtilityTest(unittest.TestCase): - - def testImergeSorted(self): - ImergeSorted = reflection._ImergeSorted - # Various types of emptiness. - self.assertEqual([], list(ImergeSorted())) - self.assertEqual([], list(ImergeSorted([]))) - self.assertEqual([], list(ImergeSorted([], []))) - - # One nonempty list. - self.assertEqual([1, 2, 3], list(ImergeSorted([1, 2, 3]))) - self.assertEqual([1, 2, 3], list(ImergeSorted([1, 2, 3], []))) - self.assertEqual([1, 2, 3], list(ImergeSorted([], [1, 2, 3]))) - - # Merging some nonempty lists together. - self.assertEqual([1, 2, 3], list(ImergeSorted([1, 3], [2]))) - self.assertEqual([1, 2, 3], list(ImergeSorted([1], [3], [2]))) - self.assertEqual([1, 2, 3], list(ImergeSorted([1], [3], [2], []))) - - # Elements repeated across component iterators. - self.assertEqual([1, 2, 2, 3, 3], - list(ImergeSorted([1, 2], [3], [2, 3]))) - - # Elements repeated within an iterator. - self.assertEqual([1, 2, 2, 3, 3], - list(ImergeSorted([1, 2, 2], [3], [3]))) - if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/test_util.py b/python/google/protobuf/internal/test_util.py index 1a0da55..1df1619 100755 --- a/python/google/protobuf/internal/test_util.py +++ b/python/google/protobuf/internal/test_util.py @@ -31,14 +31,13 @@ """Utilities for Python proto2 tests. This is intentionally modeled on C++ code in -//net/proto2/internal/test_util.*. +//google/protobuf/test_util.*. """ __author__ = 'robinson@google.com (Will Robinson)' import os.path -import unittest from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_pb2 @@ -353,198 +352,198 @@ def ExpectAllFieldsAndExtensionsInOrder(serialized): raise ValueError('Expected %r, found %r' % (expected, serialized)) -class GoldenMessageTestCase(unittest.TestCase): - """This adds methods to TestCase useful for verifying our Golden Message.""" - - def ExpectAllFieldsSet(self, message): - """Check all fields for correct values have after Set*Fields() is called.""" - self.assertTrue(message.HasField('optional_int32')) - self.assertTrue(message.HasField('optional_int64')) - self.assertTrue(message.HasField('optional_uint32')) - self.assertTrue(message.HasField('optional_uint64')) - self.assertTrue(message.HasField('optional_sint32')) - self.assertTrue(message.HasField('optional_sint64')) - self.assertTrue(message.HasField('optional_fixed32')) - self.assertTrue(message.HasField('optional_fixed64')) - self.assertTrue(message.HasField('optional_sfixed32')) - self.assertTrue(message.HasField('optional_sfixed64')) - self.assertTrue(message.HasField('optional_float')) - self.assertTrue(message.HasField('optional_double')) - self.assertTrue(message.HasField('optional_bool')) - self.assertTrue(message.HasField('optional_string')) - self.assertTrue(message.HasField('optional_bytes')) - - self.assertTrue(message.HasField('optionalgroup')) - self.assertTrue(message.HasField('optional_nested_message')) - self.assertTrue(message.HasField('optional_foreign_message')) - self.assertTrue(message.HasField('optional_import_message')) - - self.assertTrue(message.optionalgroup.HasField('a')) - self.assertTrue(message.optional_nested_message.HasField('bb')) - self.assertTrue(message.optional_foreign_message.HasField('c')) - self.assertTrue(message.optional_import_message.HasField('d')) - - self.assertTrue(message.HasField('optional_nested_enum')) - self.assertTrue(message.HasField('optional_foreign_enum')) - self.assertTrue(message.HasField('optional_import_enum')) - - self.assertTrue(message.HasField('optional_string_piece')) - self.assertTrue(message.HasField('optional_cord')) - - self.assertEqual(101, message.optional_int32) - self.assertEqual(102, message.optional_int64) - self.assertEqual(103, message.optional_uint32) - self.assertEqual(104, message.optional_uint64) - self.assertEqual(105, message.optional_sint32) - self.assertEqual(106, message.optional_sint64) - self.assertEqual(107, message.optional_fixed32) - self.assertEqual(108, message.optional_fixed64) - self.assertEqual(109, message.optional_sfixed32) - self.assertEqual(110, message.optional_sfixed64) - self.assertEqual(111, message.optional_float) - self.assertEqual(112, message.optional_double) - self.assertEqual(True, message.optional_bool) - self.assertEqual('115', message.optional_string) - self.assertEqual('116', message.optional_bytes) - - self.assertEqual(117, message.optionalgroup.a); - self.assertEqual(118, message.optional_nested_message.bb) - self.assertEqual(119, message.optional_foreign_message.c) - self.assertEqual(120, message.optional_import_message.d) - - self.assertEqual(unittest_pb2.TestAllTypes.BAZ, - message.optional_nested_enum) - self.assertEqual(unittest_pb2.FOREIGN_BAZ, message.optional_foreign_enum) - self.assertEqual(unittest_import_pb2.IMPORT_BAZ, - message.optional_import_enum) - - # ----------------------------------------------------------------- - - self.assertEqual(2, len(message.repeated_int32)) - self.assertEqual(2, len(message.repeated_int64)) - self.assertEqual(2, len(message.repeated_uint32)) - self.assertEqual(2, len(message.repeated_uint64)) - self.assertEqual(2, len(message.repeated_sint32)) - self.assertEqual(2, len(message.repeated_sint64)) - self.assertEqual(2, len(message.repeated_fixed32)) - self.assertEqual(2, len(message.repeated_fixed64)) - self.assertEqual(2, len(message.repeated_sfixed32)) - self.assertEqual(2, len(message.repeated_sfixed64)) - self.assertEqual(2, len(message.repeated_float)) - self.assertEqual(2, len(message.repeated_double)) - self.assertEqual(2, len(message.repeated_bool)) - self.assertEqual(2, len(message.repeated_string)) - self.assertEqual(2, len(message.repeated_bytes)) - - self.assertEqual(2, len(message.repeatedgroup)) - self.assertEqual(2, len(message.repeated_nested_message)) - self.assertEqual(2, len(message.repeated_foreign_message)) - self.assertEqual(2, len(message.repeated_import_message)) - self.assertEqual(2, len(message.repeated_nested_enum)) - self.assertEqual(2, len(message.repeated_foreign_enum)) - self.assertEqual(2, len(message.repeated_import_enum)) - - self.assertEqual(2, len(message.repeated_string_piece)) - self.assertEqual(2, len(message.repeated_cord)) - - self.assertEqual(201, message.repeated_int32[0]) - self.assertEqual(202, message.repeated_int64[0]) - self.assertEqual(203, message.repeated_uint32[0]) - self.assertEqual(204, message.repeated_uint64[0]) - self.assertEqual(205, message.repeated_sint32[0]) - self.assertEqual(206, message.repeated_sint64[0]) - self.assertEqual(207, message.repeated_fixed32[0]) - self.assertEqual(208, message.repeated_fixed64[0]) - self.assertEqual(209, message.repeated_sfixed32[0]) - self.assertEqual(210, message.repeated_sfixed64[0]) - self.assertEqual(211, message.repeated_float[0]) - self.assertEqual(212, message.repeated_double[0]) - self.assertEqual(True, message.repeated_bool[0]) - self.assertEqual('215', message.repeated_string[0]) - self.assertEqual('216', message.repeated_bytes[0]) - - self.assertEqual(217, message.repeatedgroup[0].a) - self.assertEqual(218, message.repeated_nested_message[0].bb) - self.assertEqual(219, message.repeated_foreign_message[0].c) - self.assertEqual(220, message.repeated_import_message[0].d) - - self.assertEqual(unittest_pb2.TestAllTypes.BAR, - message.repeated_nested_enum[0]) - self.assertEqual(unittest_pb2.FOREIGN_BAR, - message.repeated_foreign_enum[0]) - self.assertEqual(unittest_import_pb2.IMPORT_BAR, - message.repeated_import_enum[0]) - - self.assertEqual(301, message.repeated_int32[1]) - self.assertEqual(302, message.repeated_int64[1]) - self.assertEqual(303, message.repeated_uint32[1]) - self.assertEqual(304, message.repeated_uint64[1]) - self.assertEqual(305, message.repeated_sint32[1]) - self.assertEqual(306, message.repeated_sint64[1]) - self.assertEqual(307, message.repeated_fixed32[1]) - self.assertEqual(308, message.repeated_fixed64[1]) - self.assertEqual(309, message.repeated_sfixed32[1]) - self.assertEqual(310, message.repeated_sfixed64[1]) - self.assertEqual(311, message.repeated_float[1]) - self.assertEqual(312, message.repeated_double[1]) - self.assertEqual(False, message.repeated_bool[1]) - self.assertEqual('315', message.repeated_string[1]) - self.assertEqual('316', message.repeated_bytes[1]) - - self.assertEqual(317, message.repeatedgroup[1].a) - self.assertEqual(318, message.repeated_nested_message[1].bb) - self.assertEqual(319, message.repeated_foreign_message[1].c) - self.assertEqual(320, message.repeated_import_message[1].d) - - self.assertEqual(unittest_pb2.TestAllTypes.BAZ, - message.repeated_nested_enum[1]) - self.assertEqual(unittest_pb2.FOREIGN_BAZ, - message.repeated_foreign_enum[1]) - self.assertEqual(unittest_import_pb2.IMPORT_BAZ, - message.repeated_import_enum[1]) - - # ----------------------------------------------------------------- - - self.assertTrue(message.HasField('default_int32')) - self.assertTrue(message.HasField('default_int64')) - self.assertTrue(message.HasField('default_uint32')) - self.assertTrue(message.HasField('default_uint64')) - self.assertTrue(message.HasField('default_sint32')) - self.assertTrue(message.HasField('default_sint64')) - self.assertTrue(message.HasField('default_fixed32')) - self.assertTrue(message.HasField('default_fixed64')) - self.assertTrue(message.HasField('default_sfixed32')) - self.assertTrue(message.HasField('default_sfixed64')) - self.assertTrue(message.HasField('default_float')) - self.assertTrue(message.HasField('default_double')) - self.assertTrue(message.HasField('default_bool')) - self.assertTrue(message.HasField('default_string')) - self.assertTrue(message.HasField('default_bytes')) - - self.assertTrue(message.HasField('default_nested_enum')) - self.assertTrue(message.HasField('default_foreign_enum')) - self.assertTrue(message.HasField('default_import_enum')) - - self.assertEqual(401, message.default_int32) - self.assertEqual(402, message.default_int64) - self.assertEqual(403, message.default_uint32) - self.assertEqual(404, message.default_uint64) - self.assertEqual(405, message.default_sint32) - self.assertEqual(406, message.default_sint64) - self.assertEqual(407, message.default_fixed32) - self.assertEqual(408, message.default_fixed64) - self.assertEqual(409, message.default_sfixed32) - self.assertEqual(410, message.default_sfixed64) - self.assertEqual(411, message.default_float) - self.assertEqual(412, message.default_double) - self.assertEqual(False, message.default_bool) - self.assertEqual('415', message.default_string) - self.assertEqual('416', message.default_bytes) - - self.assertEqual(unittest_pb2.TestAllTypes.FOO, message.default_nested_enum) - self.assertEqual(unittest_pb2.FOREIGN_FOO, message.default_foreign_enum) - self.assertEqual(unittest_import_pb2.IMPORT_FOO, - message.default_import_enum) +def ExpectAllFieldsSet(test_case, message): + """Check all fields for correct values have after Set*Fields() is called.""" + test_case.assertTrue(message.HasField('optional_int32')) + test_case.assertTrue(message.HasField('optional_int64')) + test_case.assertTrue(message.HasField('optional_uint32')) + test_case.assertTrue(message.HasField('optional_uint64')) + test_case.assertTrue(message.HasField('optional_sint32')) + test_case.assertTrue(message.HasField('optional_sint64')) + test_case.assertTrue(message.HasField('optional_fixed32')) + test_case.assertTrue(message.HasField('optional_fixed64')) + test_case.assertTrue(message.HasField('optional_sfixed32')) + test_case.assertTrue(message.HasField('optional_sfixed64')) + test_case.assertTrue(message.HasField('optional_float')) + test_case.assertTrue(message.HasField('optional_double')) + test_case.assertTrue(message.HasField('optional_bool')) + test_case.assertTrue(message.HasField('optional_string')) + test_case.assertTrue(message.HasField('optional_bytes')) + + test_case.assertTrue(message.HasField('optionalgroup')) + test_case.assertTrue(message.HasField('optional_nested_message')) + test_case.assertTrue(message.HasField('optional_foreign_message')) + test_case.assertTrue(message.HasField('optional_import_message')) + + test_case.assertTrue(message.optionalgroup.HasField('a')) + test_case.assertTrue(message.optional_nested_message.HasField('bb')) + test_case.assertTrue(message.optional_foreign_message.HasField('c')) + test_case.assertTrue(message.optional_import_message.HasField('d')) + + test_case.assertTrue(message.HasField('optional_nested_enum')) + test_case.assertTrue(message.HasField('optional_foreign_enum')) + test_case.assertTrue(message.HasField('optional_import_enum')) + + test_case.assertTrue(message.HasField('optional_string_piece')) + test_case.assertTrue(message.HasField('optional_cord')) + + test_case.assertEqual(101, message.optional_int32) + test_case.assertEqual(102, message.optional_int64) + test_case.assertEqual(103, message.optional_uint32) + test_case.assertEqual(104, message.optional_uint64) + test_case.assertEqual(105, message.optional_sint32) + test_case.assertEqual(106, message.optional_sint64) + test_case.assertEqual(107, message.optional_fixed32) + test_case.assertEqual(108, message.optional_fixed64) + test_case.assertEqual(109, message.optional_sfixed32) + test_case.assertEqual(110, message.optional_sfixed64) + test_case.assertEqual(111, message.optional_float) + test_case.assertEqual(112, message.optional_double) + test_case.assertEqual(True, message.optional_bool) + test_case.assertEqual('115', message.optional_string) + test_case.assertEqual('116', message.optional_bytes) + + test_case.assertEqual(117, message.optionalgroup.a) + test_case.assertEqual(118, message.optional_nested_message.bb) + test_case.assertEqual(119, message.optional_foreign_message.c) + test_case.assertEqual(120, message.optional_import_message.d) + + test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ, + message.optional_nested_enum) + test_case.assertEqual(unittest_pb2.FOREIGN_BAZ, + message.optional_foreign_enum) + test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ, + message.optional_import_enum) + + # ----------------------------------------------------------------- + + test_case.assertEqual(2, len(message.repeated_int32)) + test_case.assertEqual(2, len(message.repeated_int64)) + test_case.assertEqual(2, len(message.repeated_uint32)) + test_case.assertEqual(2, len(message.repeated_uint64)) + test_case.assertEqual(2, len(message.repeated_sint32)) + test_case.assertEqual(2, len(message.repeated_sint64)) + test_case.assertEqual(2, len(message.repeated_fixed32)) + test_case.assertEqual(2, len(message.repeated_fixed64)) + test_case.assertEqual(2, len(message.repeated_sfixed32)) + test_case.assertEqual(2, len(message.repeated_sfixed64)) + test_case.assertEqual(2, len(message.repeated_float)) + test_case.assertEqual(2, len(message.repeated_double)) + test_case.assertEqual(2, len(message.repeated_bool)) + test_case.assertEqual(2, len(message.repeated_string)) + test_case.assertEqual(2, len(message.repeated_bytes)) + + test_case.assertEqual(2, len(message.repeatedgroup)) + test_case.assertEqual(2, len(message.repeated_nested_message)) + test_case.assertEqual(2, len(message.repeated_foreign_message)) + test_case.assertEqual(2, len(message.repeated_import_message)) + test_case.assertEqual(2, len(message.repeated_nested_enum)) + test_case.assertEqual(2, len(message.repeated_foreign_enum)) + test_case.assertEqual(2, len(message.repeated_import_enum)) + + test_case.assertEqual(2, len(message.repeated_string_piece)) + test_case.assertEqual(2, len(message.repeated_cord)) + + test_case.assertEqual(201, message.repeated_int32[0]) + test_case.assertEqual(202, message.repeated_int64[0]) + test_case.assertEqual(203, message.repeated_uint32[0]) + test_case.assertEqual(204, message.repeated_uint64[0]) + test_case.assertEqual(205, message.repeated_sint32[0]) + test_case.assertEqual(206, message.repeated_sint64[0]) + test_case.assertEqual(207, message.repeated_fixed32[0]) + test_case.assertEqual(208, message.repeated_fixed64[0]) + test_case.assertEqual(209, message.repeated_sfixed32[0]) + test_case.assertEqual(210, message.repeated_sfixed64[0]) + test_case.assertEqual(211, message.repeated_float[0]) + test_case.assertEqual(212, message.repeated_double[0]) + test_case.assertEqual(True, message.repeated_bool[0]) + test_case.assertEqual('215', message.repeated_string[0]) + test_case.assertEqual('216', message.repeated_bytes[0]) + + test_case.assertEqual(217, message.repeatedgroup[0].a) + test_case.assertEqual(218, message.repeated_nested_message[0].bb) + test_case.assertEqual(219, message.repeated_foreign_message[0].c) + test_case.assertEqual(220, message.repeated_import_message[0].d) + + test_case.assertEqual(unittest_pb2.TestAllTypes.BAR, + message.repeated_nested_enum[0]) + test_case.assertEqual(unittest_pb2.FOREIGN_BAR, + message.repeated_foreign_enum[0]) + test_case.assertEqual(unittest_import_pb2.IMPORT_BAR, + message.repeated_import_enum[0]) + + test_case.assertEqual(301, message.repeated_int32[1]) + test_case.assertEqual(302, message.repeated_int64[1]) + test_case.assertEqual(303, message.repeated_uint32[1]) + test_case.assertEqual(304, message.repeated_uint64[1]) + test_case.assertEqual(305, message.repeated_sint32[1]) + test_case.assertEqual(306, message.repeated_sint64[1]) + test_case.assertEqual(307, message.repeated_fixed32[1]) + test_case.assertEqual(308, message.repeated_fixed64[1]) + test_case.assertEqual(309, message.repeated_sfixed32[1]) + test_case.assertEqual(310, message.repeated_sfixed64[1]) + test_case.assertEqual(311, message.repeated_float[1]) + test_case.assertEqual(312, message.repeated_double[1]) + test_case.assertEqual(False, message.repeated_bool[1]) + test_case.assertEqual('315', message.repeated_string[1]) + test_case.assertEqual('316', message.repeated_bytes[1]) + + test_case.assertEqual(317, message.repeatedgroup[1].a) + test_case.assertEqual(318, message.repeated_nested_message[1].bb) + test_case.assertEqual(319, message.repeated_foreign_message[1].c) + test_case.assertEqual(320, message.repeated_import_message[1].d) + + test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ, + message.repeated_nested_enum[1]) + test_case.assertEqual(unittest_pb2.FOREIGN_BAZ, + message.repeated_foreign_enum[1]) + test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ, + message.repeated_import_enum[1]) + + # ----------------------------------------------------------------- + + test_case.assertTrue(message.HasField('default_int32')) + test_case.assertTrue(message.HasField('default_int64')) + test_case.assertTrue(message.HasField('default_uint32')) + test_case.assertTrue(message.HasField('default_uint64')) + test_case.assertTrue(message.HasField('default_sint32')) + test_case.assertTrue(message.HasField('default_sint64')) + test_case.assertTrue(message.HasField('default_fixed32')) + test_case.assertTrue(message.HasField('default_fixed64')) + test_case.assertTrue(message.HasField('default_sfixed32')) + test_case.assertTrue(message.HasField('default_sfixed64')) + test_case.assertTrue(message.HasField('default_float')) + test_case.assertTrue(message.HasField('default_double')) + test_case.assertTrue(message.HasField('default_bool')) + test_case.assertTrue(message.HasField('default_string')) + test_case.assertTrue(message.HasField('default_bytes')) + + test_case.assertTrue(message.HasField('default_nested_enum')) + test_case.assertTrue(message.HasField('default_foreign_enum')) + test_case.assertTrue(message.HasField('default_import_enum')) + + test_case.assertEqual(401, message.default_int32) + test_case.assertEqual(402, message.default_int64) + test_case.assertEqual(403, message.default_uint32) + test_case.assertEqual(404, message.default_uint64) + test_case.assertEqual(405, message.default_sint32) + test_case.assertEqual(406, message.default_sint64) + test_case.assertEqual(407, message.default_fixed32) + test_case.assertEqual(408, message.default_fixed64) + test_case.assertEqual(409, message.default_sfixed32) + test_case.assertEqual(410, message.default_sfixed64) + test_case.assertEqual(411, message.default_float) + test_case.assertEqual(412, message.default_double) + test_case.assertEqual(False, message.default_bool) + test_case.assertEqual('415', message.default_string) + test_case.assertEqual('416', message.default_bytes) + + test_case.assertEqual(unittest_pb2.TestAllTypes.FOO, + message.default_nested_enum) + test_case.assertEqual(unittest_pb2.FOREIGN_FOO, + message.default_foreign_enum) + test_case.assertEqual(unittest_import_pb2.IMPORT_FOO, + message.default_import_enum) def GoldenFile(filename): """Finds the given golden file and returns a file object representing it.""" @@ -570,21 +569,21 @@ def SetAllPackedFields(message): Args: message: A unittest_pb2.TestPackedTypes instance. """ - message.packed_int32.extend([101, 102]) - message.packed_int64.extend([103, 104]) - message.packed_uint32.extend([105, 106]) - message.packed_uint64.extend([107, 108]) - message.packed_sint32.extend([109, 110]) - message.packed_sint64.extend([111, 112]) - message.packed_fixed32.extend([113, 114]) - message.packed_fixed64.extend([115, 116]) - message.packed_sfixed32.extend([117, 118]) - message.packed_sfixed64.extend([119, 120]) - message.packed_float.extend([121.0, 122.0]) - message.packed_double.extend([122.0, 123.0]) + message.packed_int32.extend([601, 701]) + message.packed_int64.extend([602, 702]) + message.packed_uint32.extend([603, 703]) + message.packed_uint64.extend([604, 704]) + message.packed_sint32.extend([605, 705]) + message.packed_sint64.extend([606, 706]) + message.packed_fixed32.extend([607, 707]) + message.packed_fixed64.extend([608, 708]) + message.packed_sfixed32.extend([609, 709]) + message.packed_sfixed64.extend([610, 710]) + message.packed_float.extend([611.0, 711.0]) + message.packed_double.extend([612.0, 712.0]) message.packed_bool.extend([True, False]) - message.packed_enum.extend([unittest_pb2.FOREIGN_FOO, - unittest_pb2.FOREIGN_BAR]) + message.packed_enum.extend([unittest_pb2.FOREIGN_BAR, + unittest_pb2.FOREIGN_BAZ]) def SetAllPackedExtensions(message): @@ -596,17 +595,41 @@ def SetAllPackedExtensions(message): extensions = message.Extensions pb2 = unittest_pb2 - extensions[pb2.packed_int32_extension].append(101) - extensions[pb2.packed_int64_extension].append(102) - extensions[pb2.packed_uint32_extension].append(103) - extensions[pb2.packed_uint64_extension].append(104) - extensions[pb2.packed_sint32_extension].append(105) - extensions[pb2.packed_sint64_extension].append(106) - extensions[pb2.packed_fixed32_extension].append(107) - extensions[pb2.packed_fixed64_extension].append(108) - extensions[pb2.packed_sfixed32_extension].append(109) - extensions[pb2.packed_sfixed64_extension].append(110) - extensions[pb2.packed_float_extension].append(111.0) - extensions[pb2.packed_double_extension].append(112.0) - extensions[pb2.packed_bool_extension].append(True) - extensions[pb2.packed_enum_extension].append(pb2.FOREIGN_BAZ) + extensions[pb2.packed_int32_extension].extend([601, 701]) + extensions[pb2.packed_int64_extension].extend([602, 702]) + extensions[pb2.packed_uint32_extension].extend([603, 703]) + extensions[pb2.packed_uint64_extension].extend([604, 704]) + extensions[pb2.packed_sint32_extension].extend([605, 705]) + extensions[pb2.packed_sint64_extension].extend([606, 706]) + extensions[pb2.packed_fixed32_extension].extend([607, 707]) + extensions[pb2.packed_fixed64_extension].extend([608, 708]) + extensions[pb2.packed_sfixed32_extension].extend([609, 709]) + extensions[pb2.packed_sfixed64_extension].extend([610, 710]) + extensions[pb2.packed_float_extension].extend([611.0, 711.0]) + extensions[pb2.packed_double_extension].extend([612.0, 712.0]) + extensions[pb2.packed_bool_extension].extend([True, False]) + extensions[pb2.packed_enum_extension].extend([unittest_pb2.FOREIGN_BAR, + unittest_pb2.FOREIGN_BAZ]) + + +def SetAllUnpackedFields(message): + """Sets every field in the message to a unique value. + + Args: + message: A unittest_pb2.TestUnpackedTypes instance. + """ + message.unpacked_int32.extend([601, 701]) + message.unpacked_int64.extend([602, 702]) + message.unpacked_uint32.extend([603, 703]) + message.unpacked_uint64.extend([604, 704]) + message.unpacked_sint32.extend([605, 705]) + message.unpacked_sint64.extend([606, 706]) + message.unpacked_fixed32.extend([607, 707]) + message.unpacked_fixed64.extend([608, 708]) + message.unpacked_sfixed32.extend([609, 709]) + message.unpacked_sfixed64.extend([610, 710]) + message.unpacked_float.extend([611.0, 711.0]) + message.unpacked_double.extend([612.0, 712.0]) + message.unpacked_bool.extend([True, False]) + message.unpacked_enum.extend([unittest_pb2.FOREIGN_BAR, + unittest_pb2.FOREIGN_BAZ]) diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 0cf2718..e0991cb 100755 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -43,7 +43,7 @@ from google.protobuf import unittest_pb2 from google.protobuf import unittest_mset_pb2 -class TextFormatTest(test_util.GoldenMessageTestCase): +class TextFormatTest(unittest.TestCase): def ReadGolden(self, golden_filename): f = test_util.GoldenFile(golden_filename) golden_lines = f.readlines() @@ -149,7 +149,7 @@ class TextFormatTest(test_util.GoldenMessageTestCase): parsed_message = unittest_pb2.TestAllTypes() text_format.Merge(ascii_text, parsed_message) self.assertEqual(message, parsed_message) - self.ExpectAllFieldsSet(message) + test_util.ExpectAllFieldsSet(self, message) def testMergeAllExtensions(self): message = unittest_pb2.TestAllExtensions() @@ -191,7 +191,8 @@ class TextFormatTest(test_util.GoldenMessageTestCase): 'repeated_double: 1.23e+22\n' 'repeated_double: 1.23e-18\n' 'repeated_string: \n' - '\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\\"\"\n') + '\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\\"\"\n' + 'repeated_string: "foo" \'corge\' "grault"') text_format.Merge(text, message) self.assertEqual(-9223372036854775808, message.repeated_int64[0]) @@ -201,6 +202,7 @@ class TextFormatTest(test_util.GoldenMessageTestCase): self.assertEqual(1.23e-18, message.repeated_double[2]) self.assertEqual( '\000\001\a\b\f\n\r\t\v\\\'\"', message.repeated_string[0]) + self.assertEqual('foocorgegrault', message.repeated_string[1]) def testMergeUnknownField(self): message = unittest_pb2.TestAllTypes() @@ -212,12 +214,18 @@ class TextFormatTest(test_util.GoldenMessageTestCase): text_format.Merge, text, message) def testMergeBadExtension(self): - message = unittest_pb2.TestAllTypes() + message = unittest_pb2.TestAllExtensions() text = '[unknown_extension]: 8\n' self.assertRaisesWithMessage( text_format.ParseError, '1:2 : Extension "unknown_extension" not registered.', text_format.Merge, text, message) + message = unittest_pb2.TestAllTypes() + self.assertRaisesWithMessage( + text_format.ParseError, + ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have ' + 'extensions.'), + text_format.Merge, text, message) def testMergeGroupNotClosed(self): message = unittest_pb2.TestAllTypes() @@ -231,6 +239,19 @@ class TextFormatTest(test_util.GoldenMessageTestCase): text_format.ParseError, '1:16 : Expected "}".', text_format.Merge, text, message) + def testMergeEmptyGroup(self): + message = unittest_pb2.TestAllTypes() + text = 'OptionalGroup: {}' + text_format.Merge(text, message) + self.assertTrue(message.HasField('optionalgroup')) + + message.Clear() + + message = unittest_pb2.TestAllTypes() + text = 'OptionalGroup: <>' + text_format.Merge(text, message) + self.assertTrue(message.HasField('optionalgroup')) + def testMergeBadEnumValue(self): message = unittest_pb2.TestAllTypes() text = 'optional_nested_enum: BARR' @@ -304,10 +325,10 @@ class TokenizerTest(unittest.TestCase): '{', (tokenizer.ConsumeIdentifier, 'A'), ':', - (tokenizer.ConsumeFloat, float('inf')), + (tokenizer.ConsumeFloat, text_format._INFINITY), (tokenizer.ConsumeIdentifier, 'B'), ':', - (tokenizer.ConsumeFloat, float('-inf')), + (tokenizer.ConsumeFloat, -text_format._INFINITY), (tokenizer.ConsumeIdentifier, 'C'), ':', (tokenizer.ConsumeBool, True), @@ -392,6 +413,16 @@ class TokenizerTest(unittest.TestCase): tokenizer = text_format._Tokenizer(text) self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool) + def testInfNan(self): + # Make sure our infinity and NaN definitions are sound. + self.assertEquals(float, type(text_format._INFINITY)) + self.assertEquals(float, type(text_format._NAN)) + self.assertTrue(text_format._NAN != text_format._NAN) + + inf_times_zero = text_format._INFINITY * 0 + self.assertTrue(inf_times_zero != inf_times_zero) + self.assertTrue(text_format._INFINITY > 0) + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py index a3bc57f..2b3cd4d 100755 --- a/python/google/protobuf/internal/type_checkers.py +++ b/python/google/protobuf/internal/type_checkers.py @@ -192,47 +192,72 @@ TYPE_TO_BYTE_SIZE_FN = { } -# Maps from field type to an unbound Encoder method F, such that -# F(encoder, field_number, value) will append the serialization -# of a value of this type to the encoder. -_Encoder = encoder.Encoder -TYPE_TO_SERIALIZE_METHOD = { - _FieldDescriptor.TYPE_DOUBLE: _Encoder.AppendDouble, - _FieldDescriptor.TYPE_FLOAT: _Encoder.AppendFloat, - _FieldDescriptor.TYPE_INT64: _Encoder.AppendInt64, - _FieldDescriptor.TYPE_UINT64: _Encoder.AppendUInt64, - _FieldDescriptor.TYPE_INT32: _Encoder.AppendInt32, - _FieldDescriptor.TYPE_FIXED64: _Encoder.AppendFixed64, - _FieldDescriptor.TYPE_FIXED32: _Encoder.AppendFixed32, - _FieldDescriptor.TYPE_BOOL: _Encoder.AppendBool, - _FieldDescriptor.TYPE_STRING: _Encoder.AppendString, - _FieldDescriptor.TYPE_GROUP: _Encoder.AppendGroup, - _FieldDescriptor.TYPE_MESSAGE: _Encoder.AppendMessage, - _FieldDescriptor.TYPE_BYTES: _Encoder.AppendBytes, - _FieldDescriptor.TYPE_UINT32: _Encoder.AppendUInt32, - _FieldDescriptor.TYPE_ENUM: _Encoder.AppendEnum, - _FieldDescriptor.TYPE_SFIXED32: _Encoder.AppendSFixed32, - _FieldDescriptor.TYPE_SFIXED64: _Encoder.AppendSFixed64, - _FieldDescriptor.TYPE_SINT32: _Encoder.AppendSInt32, - _FieldDescriptor.TYPE_SINT64: _Encoder.AppendSInt64, +# Maps from field types to encoder constructors. +TYPE_TO_ENCODER = { + _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder, + _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder, + _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder, + _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder, + _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder, + _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder, + _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder, + _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder, + _FieldDescriptor.TYPE_STRING: encoder.StringEncoder, + _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder, + _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder, + _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder, + _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder, + _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder, + _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder, + _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder, + _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder, + _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder, } -TYPE_TO_NOTAG_SERIALIZE_METHOD = { - _FieldDescriptor.TYPE_DOUBLE: _Encoder.AppendDoubleNoTag, - _FieldDescriptor.TYPE_FLOAT: _Encoder.AppendFloatNoTag, - _FieldDescriptor.TYPE_INT64: _Encoder.AppendInt64NoTag, - _FieldDescriptor.TYPE_UINT64: _Encoder.AppendUInt64NoTag, - _FieldDescriptor.TYPE_INT32: _Encoder.AppendInt32NoTag, - _FieldDescriptor.TYPE_FIXED64: _Encoder.AppendFixed64NoTag, - _FieldDescriptor.TYPE_FIXED32: _Encoder.AppendFixed32NoTag, - _FieldDescriptor.TYPE_BOOL: _Encoder.AppendBoolNoTag, - _FieldDescriptor.TYPE_UINT32: _Encoder.AppendUInt32NoTag, - _FieldDescriptor.TYPE_ENUM: _Encoder.AppendEnumNoTag, - _FieldDescriptor.TYPE_SFIXED32: _Encoder.AppendSFixed32NoTag, - _FieldDescriptor.TYPE_SFIXED64: _Encoder.AppendSFixed64NoTag, - _FieldDescriptor.TYPE_SINT32: _Encoder.AppendSInt32NoTag, - _FieldDescriptor.TYPE_SINT64: _Encoder.AppendSInt64NoTag, +# Maps from field types to sizer constructors. +TYPE_TO_SIZER = { + _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer, + _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer, + _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer, + _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer, + _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer, + _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer, + _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer, + _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer, + _FieldDescriptor.TYPE_STRING: encoder.StringSizer, + _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer, + _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer, + _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer, + _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer, + _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer, + _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer, + _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer, + _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer, + _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer, + } + + +# Maps from field type to a decoder constructor. +TYPE_TO_DECODER = { + _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder, + _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder, + _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder, + _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder, + _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder, + _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder, + _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder, + _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder, + _FieldDescriptor.TYPE_STRING: decoder.StringDecoder, + _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder, + _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder, + _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder, + _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder, + _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder, + _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder, + _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder, + _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder, + _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder, } # Maps from field type to expected wiretype. @@ -259,29 +284,3 @@ FIELD_TYPE_TO_WIRE_TYPE = { _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, } - - -# Maps from field type to an unbound Decoder method F, -# such that F(decoder) will read a field of the requested type. -# -# Note that Message and Group are intentionally missing here. -# They're handled by _RecursivelyMerge(). -_Decoder = decoder.Decoder -TYPE_TO_DESERIALIZE_METHOD = { - _FieldDescriptor.TYPE_DOUBLE: _Decoder.ReadDouble, - _FieldDescriptor.TYPE_FLOAT: _Decoder.ReadFloat, - _FieldDescriptor.TYPE_INT64: _Decoder.ReadInt64, - _FieldDescriptor.TYPE_UINT64: _Decoder.ReadUInt64, - _FieldDescriptor.TYPE_INT32: _Decoder.ReadInt32, - _FieldDescriptor.TYPE_FIXED64: _Decoder.ReadFixed64, - _FieldDescriptor.TYPE_FIXED32: _Decoder.ReadFixed32, - _FieldDescriptor.TYPE_BOOL: _Decoder.ReadBool, - _FieldDescriptor.TYPE_STRING: _Decoder.ReadString, - _FieldDescriptor.TYPE_BYTES: _Decoder.ReadBytes, - _FieldDescriptor.TYPE_UINT32: _Decoder.ReadUInt32, - _FieldDescriptor.TYPE_ENUM: _Decoder.ReadEnum, - _FieldDescriptor.TYPE_SFIXED32: _Decoder.ReadSFixed32, - _FieldDescriptor.TYPE_SFIXED64: _Decoder.ReadSFixed64, - _FieldDescriptor.TYPE_SINT32: _Decoder.ReadSInt32, - _FieldDescriptor.TYPE_SINT64: _Decoder.ReadSInt64, - } diff --git a/python/google/protobuf/internal/wire_format.py b/python/google/protobuf/internal/wire_format.py index da6464d..c941fe1 100755 --- a/python/google/protobuf/internal/wire_format.py +++ b/python/google/protobuf/internal/wire_format.py @@ -33,16 +33,17 @@ __author__ = 'robinson@google.com (Will Robinson)' import struct +from google.protobuf import descriptor from google.protobuf import message TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. -_TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 +TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 # These numbers identify the wire type of a protocol buffer value. # We use the least-significant TAG_TYPE_BITS bits of the varint-encoded # tag-and-type to store one of these WIRETYPE_* constants. -# These values must match WireType enum in //net/proto2/public/wire_format.h. +# These values must match WireType enum in google/protobuf/wire_format.h. WIRETYPE_VARINT = 0 WIRETYPE_FIXED64 = 1 WIRETYPE_LENGTH_DELIMITED = 2 @@ -93,7 +94,7 @@ def UnpackTag(tag): """The inverse of PackTag(). Given an unsigned 32-bit number, returns a (field_number, wire_type) tuple. """ - return (tag >> TAG_TYPE_BITS), (tag & _TAG_TYPE_MASK) + return (tag >> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK) def ZigZagEncode(value): @@ -245,3 +246,23 @@ def _VarUInt64ByteSizeNoTag(uint64): if uint64 > UINT64_MAX: raise message.EncodeError('Value out of range: %d' % uint64) return 10 + + +NON_PACKABLE_TYPES = ( + descriptor.FieldDescriptor.TYPE_STRING, + descriptor.FieldDescriptor.TYPE_GROUP, + descriptor.FieldDescriptor.TYPE_MESSAGE, + descriptor.FieldDescriptor.TYPE_BYTES +) + + +def IsTypePackable(field_type): + """Return true iff packable = true is valid for fields of this type. + + Args: + field_type: a FieldDescriptor::Type value. + + Returns: + True iff fields of this type are packable. + """ + return field_type not in NON_PACKABLE_TYPES diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py index 9a88bdc..f839847 100755 --- a/python/google/protobuf/message.py +++ b/python/google/protobuf/message.py @@ -99,7 +99,7 @@ class Message(object): Args: other_msg: Message to copy into the current one. """ - if self == other_msg: + if self is other_msg: return self.Clear() self.MergeFrom(other_msg) @@ -108,6 +108,15 @@ class Message(object): """Clears all data that was set in the message.""" raise NotImplementedError + def SetInParent(self): + """Mark this as present in the parent. + + This normally happens automatically when you assign a field of a + sub-message, but sometimes you want to make the sub-message + present while keeping it empty. If you find yourself using this, + you may want to reconsider your design.""" + raise NotImplementedError + def IsInitialized(self): """Checks if the message is initialized. diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py index d65d8b6..5b23803 100755 --- a/python/google/protobuf/reflection.py +++ b/python/google/protobuf/reflection.py @@ -50,9 +50,13 @@ this file*. __author__ = 'robinson@google.com (Will Robinson)' -import heapq -import threading +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO +import struct import weakref + # We use "as" to avoid name collisions with variables. from google.protobuf.internal import containers from google.protobuf.internal import decoder @@ -139,14 +143,26 @@ class GeneratedProtocolMessageType(type): type. """ descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] + + cls._decoders_by_tag = {} + cls._extensions_by_name = {} + cls._extensions_by_number = {} + if (descriptor.has_options and + descriptor.GetOptions().message_set_wire_format): + cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( + decoder.MessageSetItemDecoder(cls._extensions_by_number)) + # We act as a "friend" class of the descriptor, setting # its _concrete_class attribute the first time we use a # given descriptor to initialize a concrete protocol message - # class. + # class. We also attach stuff to each FieldDescriptor for quick + # lookup later on. concrete_class_attr_name = '_concrete_class' if not hasattr(descriptor, concrete_class_attr_name): setattr(descriptor, concrete_class_attr_name, cls) - cls._known_extensions = [] + for field in descriptor.fields: + _AttachFieldHelpers(cls, field) + _AddEnumValues(descriptor, cls) _AddInitMethod(descriptor, cls) _AddPropertiesForFields(descriptor, cls) @@ -184,30 +200,33 @@ def _PropertyName(proto_field_name): # return proto_field_name + "_" # return proto_field_name # """ + # Kenton says: The above is a BAD IDEA. People rely on being able to use + # getattr() and setattr() to reflectively manipulate field values. If we + # rename the properties, then every such user has to also make sure to apply + # the same transformation. Note that currently if you name a field "yield", + # you can still access it just fine using getattr/setattr -- it's not even + # that cumbersome to do so. + # TODO(kenton): Remove this method entirely if/when everyone agrees with my + # position. return proto_field_name -def _ValueFieldName(proto_field_name): - """Returns the name of the (internal) instance attribute which objects - should use to store the current value for a given protocol message field. - - Args: - proto_field_name: The protocol message field name, exactly - as it appears (or would appear) in a .proto file. - """ - return '_value_' + proto_field_name +def _VerifyExtensionHandle(message, extension_handle): + """Verify that the given extension handle is valid.""" + if not isinstance(extension_handle, _FieldDescriptor): + raise KeyError('HasExtension() expects an extension handle, got: %s' % + extension_handle) -def _HasFieldName(proto_field_name): - """Returns the name of the (internal) instance attribute which - objects should use to store a boolean telling whether this field - is explicitly set or not. + if not extension_handle.is_extension: + raise KeyError('"%s" is not an extension.' % extension_handle.full_name) - Args: - proto_field_name: The protocol message field name, exactly - as it appears (or would appear) in a .proto file. - """ - return '_has_' + proto_field_name + if extension_handle.containing_type is not message.DESCRIPTOR: + raise KeyError('Extension "%s" extends message type "%s", but this ' + 'message is of type "%s".' % + (extension_handle.full_name, + extension_handle.containing_type.full_name, + message.DESCRIPTOR.full_name)) def _AddSlots(message_descriptor, dictionary): @@ -218,16 +237,57 @@ def _AddSlots(message_descriptor, dictionary): message_descriptor: A Descriptor instance describing this message type. dictionary: Class dictionary to which we'll add a '__slots__' entry. """ - field_names = [_ValueFieldName(f.name) for f in message_descriptor.fields] - field_names.extend(_HasFieldName(f.name) for f in message_descriptor.fields - if f.label != _FieldDescriptor.LABEL_REPEATED) - field_names.extend(('Extensions', - '_cached_byte_size', - '_cached_byte_size_dirty', - '_called_transition_to_nonempty', - '_listener', - '_lock', '__weakref__')) - dictionary['__slots__'] = field_names + dictionary['__slots__'] = ['_cached_byte_size', + '_cached_byte_size_dirty', + '_fields', + '_is_present_in_parent', + '_listener', + '_listener_for_children', + '__weakref__'] + + +def _IsMessageSetExtension(field): + return (field.is_extension and + field.containing_type.has_options and + field.containing_type.GetOptions().message_set_wire_format and + field.type == _FieldDescriptor.TYPE_MESSAGE and + field.message_type == field.extension_scope and + field.label == _FieldDescriptor.LABEL_OPTIONAL) + + +def _AttachFieldHelpers(cls, field_descriptor): + is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) + is_packed = (field_descriptor.has_options and + field_descriptor.GetOptions().packed) + + if _IsMessageSetExtension(field_descriptor): + field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) + sizer = encoder.MessageSetItemSizer(field_descriptor.number) + else: + field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed) + sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed) + + field_descriptor._encoder = field_encoder + field_descriptor._sizer = sizer + field_descriptor._default_constructor = _DefaultValueConstructorForField( + field_descriptor) + + def AddDecoder(wiretype, is_packed): + tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) + cls._decoders_by_tag[tag_bytes] = ( + type_checkers.TYPE_TO_DECODER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed, + field_descriptor, field_descriptor._default_constructor)) + + AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], + False) + + if is_repeated and wire_format.IsTypePackable(field_descriptor.type): + # To support wire compatibility of adding packed = true, add a decoder for + # packed values regardless of the field's options. + AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) def _AddClassAttributesForNestedExtensions(descriptor, dictionary): @@ -249,44 +309,51 @@ def _AddEnumValues(descriptor, cls): setattr(cls, enum_value.name, enum_value.number) -def _DefaultValueForField(message, field): - """Returns a default value for a field. +def _DefaultValueConstructorForField(field): + """Returns a function which returns a default value for a field. Args: + field: FieldDescriptor object for this field. + + The returned function has one argument: message: Message instance containing this field, or a weakref proxy of same. - field: FieldDescriptor object for this field. - Returns: A default value for this field. May refer back to |message| - via a weak reference. + That function in turn returns a default value for this field. The default + value may refer back to |message| via a weak reference. """ - # TODO(robinson): Only the repeated fields need a reference to 'message' (so - # that they can set the 'has' bit on the containing Message when someone - # append()s a value). We could special-case this, and avoid an extra - # function call on __init__() and Clear() for non-repeated fields. - - # TODO(robinson): Find a better place for the default value assertion in this - # function. No need to repeat them every time the client calls Clear('foo'). - # (We should probably just assert these things once and as early as possible, - # by tightening checking in the descriptor classes.) + if field.label == _FieldDescriptor.LABEL_REPEATED: if field.default_value != []: raise ValueError('Repeated field default value not empty list: %s' % ( field.default_value)) - listener = _Listener(message, None) if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # We can't look at _concrete_class yet since it might not have # been set. (Depends on order in which we initialize the classes). - return containers.RepeatedCompositeFieldContainer( - listener, field.message_type) + message_type = field.message_type + def MakeRepeatedMessageDefault(message): + return containers.RepeatedCompositeFieldContainer( + message._listener_for_children, field.message_type) + return MakeRepeatedMessageDefault else: - return containers.RepeatedScalarFieldContainer( - listener, type_checkers.GetTypeChecker(field.cpp_type, field.type)) + type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) + def MakeRepeatedScalarDefault(message): + return containers.RepeatedScalarFieldContainer( + message._listener_for_children, type_checker) + return MakeRepeatedScalarDefault if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - assert field.default_value is None + # _concrete_class may not yet be initialized. + message_type = field.message_type + def MakeSubMessageDefault(message): + result = message_type._concrete_class() + result._SetListener(message._listener_for_children) + return result + return MakeSubMessageDefault - return field.default_value + def MakeScalarDefault(message): + return field.default_value + return MakeScalarDefault def _AddInitMethod(message_descriptor, cls): @@ -295,21 +362,29 @@ def _AddInitMethod(message_descriptor, cls): def init(self, **kwargs): self._cached_byte_size = 0 self._cached_byte_size_dirty = False + self._fields = {} + self._is_present_in_parent = False self._listener = message_listener_mod.NullMessageListener() - self._called_transition_to_nonempty = False - # TODO(robinson): We should only create a lock if we really need one - # in this class. - self._lock = threading.Lock() - for field in fields: - default_value = _DefaultValueForField(self, field) - python_field_name = _ValueFieldName(field.name) - setattr(self, python_field_name, default_value) - if field.label != _FieldDescriptor.LABEL_REPEATED: - setattr(self, _HasFieldName(field.name), False) - self.Extensions = _ExtensionDict(self, cls._known_extensions) + self._listener_for_children = _Listener(self) for field_name, field_value in kwargs.iteritems(): field = _GetFieldByName(message_descriptor, field_name) - _MergeFieldOrExtension(self, field, field_value) + if field is None: + raise TypeError("%s() got an unexpected keyword argument '%s'" % + (message_descriptor.name, field_name)) + if field.label == _FieldDescriptor.LABEL_REPEATED: + copy = field._default_constructor(self) + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite + for val in field_value: + copy.add().MergeFrom(val) + else: # Scalar + copy.extend(field_value) + self._fields[field] = copy + elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + copy = field._default_constructor(self) + copy.MergeFrom(field_value) + self._fields[field] = copy + else: + self._fields[field] = field_value init.__module__ = None init.__doc__ = None @@ -336,6 +411,11 @@ def _AddPropertiesForFields(descriptor, cls): for field in descriptor.fields: _AddPropertiesForField(field, cls) + if descriptor.is_extendable: + # _ExtensionDict is just an adaptor with no state so we allocate a new one + # every time it is accessed. + cls.Extensions = property(lambda self: _ExtensionDict(self)) + def _AddPropertiesForField(field, cls): """Adds a public property for a protocol message field. @@ -377,11 +457,22 @@ def _AddPropertiesForRepeatedField(field, cls): cls: The class we're constructing. """ proto_field_name = field.name - python_field_name = _ValueFieldName(proto_field_name) property_name = _PropertyName(proto_field_name) def getter(self): - return getattr(self, python_field_name) + field_value = self._fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) + return field_value getter.__module__ = None getter.__doc__ = 'Getter for %s.' % proto_field_name @@ -407,21 +498,21 @@ def _AddPropertiesForNonRepeatedScalarField(field, cls): cls: The class we're constructing. """ proto_field_name = field.name - python_field_name = _ValueFieldName(proto_field_name) - has_field_name = _HasFieldName(proto_field_name) property_name = _PropertyName(proto_field_name) type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) + default_value = field.default_value def getter(self): - return getattr(self, python_field_name) + return self._fields.get(field, default_value) getter.__module__ = None getter.__doc__ = 'Getter for %s.' % proto_field_name def setter(self, new_value): type_checker.CheckValue(new_value) - setattr(self, has_field_name, True) - self._MarkByteSizeDirty() - self._MaybeCallTransitionToNonemptyCallback() - setattr(self, python_field_name, new_value) + self._fields[field] = new_value + # Check _cached_byte_size_dirty inline to improve performance, since scalar + # setters are called frequently. + if not self._cached_byte_size_dirty: + self._Modified() setter.__module__ = None setter.__doc__ = 'Setter for %s.' % proto_field_name @@ -444,25 +535,23 @@ def _AddPropertiesForNonRepeatedCompositeField(field, cls): # TODO(robinson): Remove duplication with similar method # for non-repeated scalars. proto_field_name = field.name - python_field_name = _ValueFieldName(proto_field_name) - has_field_name = _HasFieldName(proto_field_name) property_name = _PropertyName(proto_field_name) message_type = field.message_type def getter(self): - # TODO(robinson): Appropriately scary note about double-checked locking. - field_value = getattr(self, python_field_name) + field_value = self._fields.get(field) if field_value is None: - self._lock.acquire() - try: - field_value = getattr(self, python_field_name) - if field_value is None: - field_class = message_type._concrete_class - field_value = field_class() - field_value._SetListener(_Listener(self, has_field_name)) - setattr(self, python_field_name, field_value) - finally: - self._lock.release() + # Construct a new object to represent this field. + field_value = message_type._concrete_class() + field_value._SetListener(self._listener_for_children) + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) return field_value getter.__module__ = None getter.__doc__ = 'Getter for %s.' % proto_field_name @@ -490,7 +579,27 @@ def _AddStaticMethods(cls): # TODO(robinson): This probably needs to be thread-safe(?) def RegisterExtension(extension_handle): extension_handle.containing_type = cls.DESCRIPTOR - cls._known_extensions.append(extension_handle) + _AttachFieldHelpers(cls, extension_handle) + + # Try to insert our extension, failing if an extension with the same number + # already exists. + actual_handle = cls._extensions_by_number.setdefault( + extension_handle.number, extension_handle) + if actual_handle is not extension_handle: + raise AssertionError( + 'Extensions "%s" and "%s" both try to extend message type "%s" with ' + 'field number %d.' % + (extension_handle.full_name, actual_handle.full_name, + cls.DESCRIPTOR.full_name, extension_handle.number)) + + cls._extensions_by_name[extension_handle.full_name] = extension_handle + + handle = extension_handle # avoid line wrapping + if _IsMessageSetExtension(handle): + # MessageSet extension. Also register under type name. + cls._extensions_by_name[ + extension_handle.message_type.full_name] = extension_handle + cls.RegisterExtension = staticmethod(RegisterExtension) def FromString(s): @@ -500,115 +609,107 @@ def _AddStaticMethods(cls): cls.FromString = staticmethod(FromString) +def _IsPresent(item): + """Given a (FieldDescriptor, value) tuple from _fields, return true if the + value should be included in the list returned by ListFields().""" + + if item[0].label == _FieldDescriptor.LABEL_REPEATED: + return bool(item[1]) + elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + return item[1]._is_present_in_parent + else: + return True + + def _AddListFieldsMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" - # Ensure that we always list in ascending field-number order. - # For non-extension fields, we can do the sort once, here, at import-time. - # For extensions, we sort on each ListFields() call, though - # we could do better if we have to. - fields = sorted(message_descriptor.fields, key=lambda f: f.number) - has_field_names = (_HasFieldName(f.name) for f in fields) - value_field_names = (_ValueFieldName(f.name) for f in fields) - triplets = zip(has_field_names, value_field_names, fields) - def ListFields(self): - # We need to list all extension and non-extension fields - # together, in sorted order by field number. - - # Step 0: Get an iterator over all "set" non-extension fields, - # sorted by field number. - # This iterator yields (field_number, field_descriptor, value) tuples. - def SortedSetFieldsIter(): - # Note that triplets is already sorted by field number. - for has_field_name, value_field_name, field_descriptor in triplets: - if field_descriptor.label == _FieldDescriptor.LABEL_REPEATED: - value = getattr(self, _ValueFieldName(field_descriptor.name)) - if len(value) > 0: - yield (field_descriptor.number, field_descriptor, value) - elif getattr(self, _HasFieldName(field_descriptor.name)): - value = getattr(self, _ValueFieldName(field_descriptor.name)) - yield (field_descriptor.number, field_descriptor, value) - sorted_fields = SortedSetFieldsIter() - - # Step 1: Get an iterator over all "set" extension fields, - # sorted by field number. - # This iterator ALSO yields (field_number, field_descriptor, value) tuples. - # TODO(robinson): It's not necessary to repeat this with each - # serialization call. We can do better. - sorted_extension_fields = sorted( - [(f.number, f, v) for f, v in self.Extensions._ListSetExtensions()]) - - # Step 2: Create a composite iterator that merges the extension- - # and non-extension fields, and that still yields fields in - # sorted order. - all_set_fields = _ImergeSorted(sorted_fields, sorted_extension_fields) - - # Step 3: Strip off the field numbers and return. - return [field[1:] for field in all_set_fields] + all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)] + all_fields.sort(key = lambda item: item[0].number) + return all_fields cls.ListFields = ListFields -def _AddHasFieldMethod(cls): + +def _AddHasFieldMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" + + singular_fields = {} + for field in message_descriptor.fields: + if field.label != _FieldDescriptor.LABEL_REPEATED: + singular_fields[field.name] = field + def HasField(self, field_name): try: - return getattr(self, _HasFieldName(field_name)) - except AttributeError: - raise ValueError('Protocol message has no "%s" field.' % field_name) + field = singular_fields[field_name] + except KeyError: + raise ValueError( + 'Protocol message has no singular "%s" field.' % field_name) + + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(field) + return value is not None and value._is_present_in_parent + else: + return field in self._fields cls.HasField = HasField -def _AddClearFieldMethod(cls): +def _AddClearFieldMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" def ClearField(self, field_name): - field = _GetFieldByName(self.DESCRIPTOR, field_name) - proto_field_name = field.name - python_field_name = _ValueFieldName(proto_field_name) - has_field_name = _HasFieldName(proto_field_name) - default_value = _DefaultValueForField(self, field) - if field.label == _FieldDescriptor.LABEL_REPEATED: - self._MarkByteSizeDirty() - else: - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - old_field_value = getattr(self, python_field_name) - if old_field_value is not None: - # Snip the old object out of the object tree. - old_field_value._SetListener(None) - if getattr(self, has_field_name): - setattr(self, has_field_name, False) - # Set dirty bit on ourself and parents only if - # we're actually changing state. - self._MarkByteSizeDirty() - setattr(self, python_field_name, default_value) + try: + field = message_descriptor.fields_by_name[field_name] + except KeyError: + raise ValueError('Protocol message has no "%s" field.' % field_name) + + if field in self._fields: + # Note: If the field is a sub-message, its listener will still point + # at us. That's fine, because the worst than can happen is that it + # will call _Modified() and invalidate our byte size. Big deal. + del self._fields[field] + + # Always call _Modified() -- even if nothing was changed, this is + # a mutating method, and thus calling it should cause the field to become + # present in the parent message. + self._Modified() + cls.ClearField = ClearField def _AddClearExtensionMethod(cls): """Helper for _AddMessageMethods().""" def ClearExtension(self, extension_handle): - self.Extensions._ClearExtension(extension_handle) + _VerifyExtensionHandle(self, extension_handle) + + # Similar to ClearField(), above. + if extension_handle in self._fields: + del self._fields[extension_handle] + self._Modified() cls.ClearExtension = ClearExtension -def _AddClearMethod(cls): +def _AddClearMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" def Clear(self): # Clear fields. - fields = self.DESCRIPTOR.fields - for field in fields: - self.ClearField(field.name) - # Clear extensions. - extensions = self.Extensions._ListSetExtensions() - for extension in extensions: - self.ClearExtension(extension[0]) + self._fields = {} + self._Modified() cls.Clear = Clear def _AddHasExtensionMethod(cls): """Helper for _AddMessageMethods().""" def HasExtension(self, extension_handle): - return self.Extensions._HasExtension(extension_handle) + _VerifyExtensionHandle(self, extension_handle) + if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: + raise KeyError('"%s" is repeated.' % extension_handle.full_name) + + if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(extension_handle) + return value is not None and value._is_present_in_parent + else: + return extension_handle in self._fields cls.HasExtension = HasExtension @@ -622,26 +723,8 @@ def _AddEqualsMethod(message_descriptor, cls): if self is other: return True - # Compare all fields contained directly in this message. - for field_descriptor in message_descriptor.fields: - label = field_descriptor.label - property_name = _PropertyName(field_descriptor.name) - # Non-repeated field equality requires matching "has" bits as well - # as having an equal value. - if label != _FieldDescriptor.LABEL_REPEATED: - self_has = self.HasField(property_name) - other_has = other.HasField(property_name) - if self_has != other_has: - return False - if not self_has: - # If the "has" bit for this field is False, we must stop here. - # Otherwise we will recurse forever on recursively-defined protos. - continue - if getattr(self, property_name) != getattr(other, property_name): - return False + return self.ListFields() == other.ListFields() - # Compare the extensions present in both messages. - return self.Extensions == other.Extensions cls.__eq__ = __eq__ @@ -685,618 +768,202 @@ def _BytesForNonRepeatedElement(value, field_number, field_type): def _AddByteSizeMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" - def BytesForField(message, field, value): - """Returns the number of bytes required to serialize a single field - in message. The field may be repeated or not, composite or not. - - Args: - message: The Message instance containing a field of the given type. - field: A FieldDescriptor describing the field of interest. - value: The value whose byte size we're interested in. - - Returns: The number of bytes required to serialize the current value - of "field" in "message", including space for tags and any other - necessary information. - """ - - if _MessageSetField(field): - return wire_format.MessageSetItemByteSize(field.number, value) - - field_number, field_type = field.number, field.type - - # Repeated fields. - if field.label == _FieldDescriptor.LABEL_REPEATED: - elements = value - else: - elements = [value] - - if field.GetOptions().packed: - content_size = _ContentBytesForPackedField(message, field, elements) - if content_size: - tag_size = wire_format.TagByteSize(field_number) - length_size = wire_format.Int32ByteSizeNoTag(content_size) - return tag_size + length_size + content_size - else: - return 0 - else: - return sum(_BytesForNonRepeatedElement(element, field_number, field_type) - for element in elements) - - def _ContentBytesForPackedField(self, field, value): - """Returns the number of bytes required to serialize the actual - content of a packed field (not including the tag or the encoding - of the length. - - Args: - self: The Message instance containing a field of the given type. - field: A FieldDescriptor describing the field of interest. - value: The value whose byte size we're interested in. - - Returns: The number of bytes required to serialize the current value - of the packed "field" in "message", excluding space for tags and the - length encoding. - """ - size = sum(_BytesForNonRepeatedElement(element, field.number, field.type) - for element in value) - # In the packed case, there are no per element tags. - return size - wire_format.TagByteSize(field.number) * len(value) - - fields = message_descriptor.fields - has_field_names = (_HasFieldName(f.name) for f in fields) - zipped = zip(has_field_names, fields) - def ByteSize(self): if not self._cached_byte_size_dirty: return self._cached_byte_size size = 0 - # Hardcoded fields first. - for has_field_name, field in zipped: - if (field.label == _FieldDescriptor.LABEL_REPEATED - or getattr(self, has_field_name)): - value = getattr(self, _ValueFieldName(field.name)) - size += BytesForField(self, field, value) - # Extensions next. - for field, value in self.Extensions._ListSetExtensions(): - size += BytesForField(self, field, value) + for field_descriptor, field_value in self.ListFields(): + size += field_descriptor._sizer(field_value) self._cached_byte_size = size self._cached_byte_size_dirty = False + self._listener_for_children.dirty = False return size - cls._ContentBytesForPackedField = _ContentBytesForPackedField cls.ByteSize = ByteSize -def _MessageSetField(field_descriptor): - """Checks if a field should be serialized using the message set wire format. - - Args: - field_descriptor: Descriptor of the field. - - Returns: - True if the field should be serialized using the message set wire format, - false otherwise. - """ - return (field_descriptor.is_extension and - field_descriptor.label != _FieldDescriptor.LABEL_REPEATED and - field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and - field_descriptor.containing_type.GetOptions().message_set_wire_format) - - -def _SerializeValueToEncoder(value, field_number, field_descriptor, encoder): - """Appends the serialization of a single value to encoder. - - Args: - value: Value to serialize. - field_number: Field number of this value. - field_descriptor: Descriptor of the field to serialize. - encoder: encoder.Encoder object to which we should serialize this value. - """ - if _MessageSetField(field_descriptor): - encoder.AppendMessageSetItem(field_number, value) - return - - try: - method = type_checkers.TYPE_TO_SERIALIZE_METHOD[field_descriptor.type] - method(encoder, field_number, value) - except KeyError: - raise message_mod.EncodeError('Unrecognized field type: %d' % - field_descriptor.type) - - -def _ImergeSorted(*streams): - """Merges N sorted iterators into a single sorted iterator. - Each element in streams must be an iterable that yields - its elements in sorted order, and the elements contained - in each stream must all be comparable. - - There may be repeated elements in the component streams or - across the streams; the repeated elements will all be repeated - in the merged iterator as well. - - I believe that the heapq module at HEAD in the Python - sources has a method like this, but for now we roll our own. - """ - iters = [iter(stream) for stream in streams] - heap = [] - for index, it in enumerate(iters): - try: - heap.append((it.next(), index)) - except StopIteration: - pass - heapq.heapify(heap) - - while heap: - smallest_value, idx = heap[0] - yield smallest_value - try: - next_element = iters[idx].next() - heapq.heapreplace(heap, (next_element, idx)) - except StopIteration: - heapq.heappop(heap) - - def _AddSerializeToStringMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" def SerializeToString(self): # Check if the message has all of its required fields set. errors = [] - if not _InternalIsInitialized(self, errors): - raise message_mod.EncodeError('\n'.join(errors)) + if not self.IsInitialized(): + raise message_mod.EncodeError( + 'Message is missing required fields: ' + + ','.join(self.FindInitializationErrors())) return self.SerializePartialToString() cls.SerializeToString = SerializeToString def _AddSerializePartialToStringMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" - Encoder = encoder.Encoder def SerializePartialToString(self): - encoder = Encoder() - # We need to serialize all extension and non-extension fields - # together, in sorted order by field number. - for field_descriptor, field_value in self.ListFields(): - if field_descriptor.label == _FieldDescriptor.LABEL_REPEATED: - repeated_value = field_value - else: - repeated_value = [field_value] - if field_descriptor.GetOptions().packed: - # First, write the field number and WIRETYPE_LENGTH_DELIMITED. - field_number = field_descriptor.number - encoder.AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - # Next, write the number of bytes. - content_bytes = self._ContentBytesForPackedField( - field_descriptor, field_value) - encoder.AppendInt32NoTag(content_bytes) - # Finally, write the actual values. - try: - method = type_checkers.TYPE_TO_NOTAG_SERIALIZE_METHOD[ - field_descriptor.type] - for value in repeated_value: - method(encoder, value) - except KeyError: - raise message_mod.EncodeError('Unrecognized field type: %d' % - field_descriptor.type) - else: - for element in repeated_value: - _SerializeValueToEncoder(element, field_descriptor.number, - field_descriptor, encoder) - return encoder.ToString() - + out = StringIO() + self._InternalSerialize(out.write) + return out.getvalue() cls.SerializePartialToString = SerializePartialToString + def InternalSerialize(self, write_bytes): + for field_descriptor, field_value in self.ListFields(): + field_descriptor._encoder(write_bytes, field_value) + cls._InternalSerialize = InternalSerialize -def _WireTypeForFieldType(field_type): - """Given a field type, returns the expected wire type.""" - try: - return type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_type] - except KeyError: - raise message_mod.DecodeError('Unknown field type: %d' % field_type) - - -def _WireTypeForField(field_descriptor): - """Given a field descriptor, returns the expected wire type.""" - if field_descriptor.GetOptions().packed: - return wire_format.WIRETYPE_LENGTH_DELIMITED - else: - return _WireTypeForFieldType(field_descriptor.type) - - -def _RecursivelyMerge(field_number, field_type, decoder, message): - """Decodes a message from decoder into message. - message is either a group or a nested message within some containing - protocol message. If it's a group, we use the group protocol to - deserialize, and if it's a nested message, we use the nested-message - protocol. - - Args: - field_number: The field number of message in its enclosing protocol buffer. - field_type: The field type of message. Must be either TYPE_MESSAGE - or TYPE_GROUP. - decoder: Decoder to read from. - message: Message to deserialize into. - """ - if field_type == _FieldDescriptor.TYPE_MESSAGE: - decoder.ReadMessageInto(message) - elif field_type == _FieldDescriptor.TYPE_GROUP: - decoder.ReadGroupInto(field_number, message) - else: - raise message_mod.DecodeError('Unexpected field type: %d' % field_type) - - -def _DeserializeScalarFromDecoder(field_type, decoder): - """Deserializes a scalar of the requested type from decoder. field_type must - be a scalar (non-group, non-message) FieldDescriptor.FIELD_* constant. - """ - try: - method = type_checkers.TYPE_TO_DESERIALIZE_METHOD[field_type] - return method(decoder) - except KeyError: - raise message_mod.DecodeError('Unrecognized field type: %d' % field_type) - - -def _SkipField(field_number, wire_type, decoder): - """Skips a field with the specified wire type. - - Args: - field_number: Tag number of the field to skip. - wire_type: Wire type of the field to skip. - decoder: Decoder used to deserialize the messsage. It must be positioned - just after reading the the tag and wire type of the field. - """ - if wire_type == wire_format.WIRETYPE_VARINT: - decoder.ReadUInt64() - elif wire_type == wire_format.WIRETYPE_FIXED64: - decoder.ReadFixed64() - elif wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED: - decoder.SkipBytes(decoder.ReadInt32()) - elif wire_type == wire_format.WIRETYPE_START_GROUP: - _SkipGroup(field_number, decoder) - elif wire_type == wire_format.WIRETYPE_END_GROUP: - pass - elif wire_type == wire_format.WIRETYPE_FIXED32: - decoder.ReadFixed32() - else: - raise message_mod.DecodeError('Unexpected wire type: %d' % wire_type) - - -def _SkipGroup(group_number, decoder): - """Skips a nested group from the decoder. - - Args: - group_number: Tag number of the group to skip. - decoder: Decoder used to deserialize the message. It must be positioned - exactly at the beginning of the message that should be skipped. - """ - while True: - field_number, wire_type = decoder.ReadFieldNumberAndWireType() - if (wire_type == wire_format.WIRETYPE_END_GROUP and - field_number == group_number): - return - _SkipField(field_number, wire_type, decoder) - - -def _DeserializeMessageSetItem(message, decoder): - """Deserializes a message using the message set wire format. - - Args: - message: Message to be parsed to. - decoder: The decoder to be used to deserialize encoded data. Note that the - decoder should be positioned just after reading the START_GROUP tag that - began the messageset item. - """ - field_number, wire_type = decoder.ReadFieldNumberAndWireType() - if wire_type != wire_format.WIRETYPE_VARINT or field_number != 2: - raise message_mod.DecodeError( - 'Incorrect message set wire format. ' - 'wire_type: %d, field_number: %d' % (wire_type, field_number)) - - type_id = decoder.ReadInt32() - field_number, wire_type = decoder.ReadFieldNumberAndWireType() - if wire_type != wire_format.WIRETYPE_LENGTH_DELIMITED or field_number != 3: - raise message_mod.DecodeError( - 'Incorrect message set wire format. ' - 'wire_type: %d, field_number: %d' % (wire_type, field_number)) - - extension_dict = message.Extensions - extensions_by_number = extension_dict._AllExtensionsByNumber() - if type_id not in extensions_by_number: - _SkipField(field_number, wire_type, decoder) - return - - field_descriptor = extensions_by_number[type_id] - value = extension_dict[field_descriptor] - decoder.ReadMessageInto(value) - # Read the END_GROUP tag. - field_number, wire_type = decoder.ReadFieldNumberAndWireType() - if wire_type != wire_format.WIRETYPE_END_GROUP or field_number != 1: - raise message_mod.DecodeError( - 'Incorrect message set wire format. ' - 'wire_type: %d, field_number: %d' % (wire_type, field_number)) - - -def _DeserializeOneEntity(message_descriptor, message, decoder): - """Deserializes the next wire entity from decoder into message. - - The next wire entity is either a scalar or a nested message, an - element in a repeated field (the wire encoding in this case is the - same), or a packed repeated field (in this case, the entire repeated - field is read by a single call to _DeserializeOneEntity). - - Args: - message_descriptor: A Descriptor instance describing all fields - in message. - message: The Message instance into which we're decoding our fields. - decoder: The Decoder we're using to deserialize encoded data. - - Returns: The number of bytes read from decoder during this method. - """ - initial_position = decoder.Position() - field_number, wire_type = decoder.ReadFieldNumberAndWireType() - extension_dict = message.Extensions - extensions_by_number = extension_dict._AllExtensionsByNumber() - if field_number in message_descriptor.fields_by_number: - # Non-extension field. - field_descriptor = message_descriptor.fields_by_number[field_number] - value = getattr(message, _PropertyName(field_descriptor.name)) - def nonextension_setter_fn(scalar): - setattr(message, _PropertyName(field_descriptor.name), scalar) - scalar_setter_fn = nonextension_setter_fn - elif field_number in extensions_by_number: - # Extension field. - field_descriptor = extensions_by_number[field_number] - value = extension_dict[field_descriptor] - def extension_setter_fn(scalar): - extension_dict[field_descriptor] = scalar - scalar_setter_fn = extension_setter_fn - elif wire_type == wire_format.WIRETYPE_END_GROUP: - # We assume we're being parsed as the group that's ended. - return 0 - elif (wire_type == wire_format.WIRETYPE_START_GROUP and - field_number == 1 and - message_descriptor.GetOptions().message_set_wire_format): - # A Message Set item. - _DeserializeMessageSetItem(message, decoder) - return decoder.Position() - initial_position - else: - _SkipField(field_number, wire_type, decoder) - return decoder.Position() - initial_position - - # If we reach this point, we've identified the field as either - # hardcoded or extension, and set |field_descriptor|, |scalar_setter_fn|, - # and |value| appropriately. Now actually deserialize the thing. - # - # field_descriptor: Describes the field we're deserializing. - # value: The value currently stored in the field to deserialize. - # Used only if the field is composite and/or repeated. - # scalar_setter_fn: A function F such that F(scalar) will - # set a nonrepeated scalar value for this field. Used only - # if this field is a nonrepeated scalar. - - field_number = field_descriptor.number - expected_wire_type = _WireTypeForField(field_descriptor) - if wire_type != expected_wire_type: - # Need to fill in uninterpreted_bytes. Work for the next CL. - raise RuntimeError('TODO(robinson): Wiretype mismatches not handled.') - - property_name = _PropertyName(field_descriptor.name) - label = field_descriptor.label - field_type = field_descriptor.type - cpp_type = field_descriptor.cpp_type - - # Nonrepeated scalar. Just set the field directly. - if (label != _FieldDescriptor.LABEL_REPEATED - and cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE): - scalar_setter_fn(_DeserializeScalarFromDecoder(field_type, decoder)) - return decoder.Position() - initial_position - - # Nonrepeated composite. Recursively deserialize. - if label != _FieldDescriptor.LABEL_REPEATED: - composite = value - _RecursivelyMerge(field_number, field_type, decoder, composite) - return decoder.Position() - initial_position - - # Now we know we're dealing with a repeated field of some kind. - element_list = value - - if cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE: - # Repeated scalar. - if not field_descriptor.GetOptions().packed: - element_list.append(_DeserializeScalarFromDecoder(field_type, decoder)) - return decoder.Position() - initial_position - else: - # Packed repeated field. - length = _DeserializeScalarFromDecoder( - _FieldDescriptor.TYPE_INT32, decoder) - content_start = decoder.Position() - while decoder.Position() - content_start < length: - element_list.append(_DeserializeScalarFromDecoder(field_type, decoder)) - return decoder.Position() - initial_position - else: - # Repeated composite. - composite = element_list.add() - _RecursivelyMerge(field_number, field_type, decoder, composite) - return decoder.Position() - initial_position - - -def _FieldOrExtensionValues(message, field_or_extension): - """Retrieves the list of values for the specified field or extension. - - The target field or extension can be optional, required or repeated, but it - must have value(s) set. The assumption is that the target field or extension - is set (e.g. _HasFieldOrExtension holds true). - Args: - message: Message which contains the target field or extension. - field_or_extension: Field or extension for which the list of values is - required. Must be an instance of FieldDescriptor. +def _AddMergeFromStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def MergeFromString(self, serialized): + length = len(serialized) + try: + if self._InternalParse(serialized, 0, length) != length: + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise message_mod.DecodeError('Unexpected end-group tag.') + except IndexError: + raise message_mod.DecodeError('Truncated message.') + except struct.error, e: + raise message_mod.DecodeError(e) + return length # Return this for legacy reasons. + cls.MergeFromString = MergeFromString - Returns: - A list of values for the specified field or extension. This list will only - contain a single element if the field is non-repeated. - """ - if field_or_extension.is_extension: - value = message.Extensions[field_or_extension] - else: - value = getattr(message, _ValueFieldName(field_or_extension.name)) - if field_or_extension.label != _FieldDescriptor.LABEL_REPEATED: - return [value] - else: - # In this case value is a list or repeated values. - return value + local_ReadTag = decoder.ReadTag + local_SkipField = decoder.SkipField + decoders_by_tag = cls._decoders_by_tag + + def InternalParse(self, buffer, pos, end): + self._Modified() + field_dict = self._fields + while pos != end: + (tag_bytes, new_pos) = local_ReadTag(buffer, pos) + field_decoder = decoders_by_tag.get(tag_bytes) + if field_decoder is None: + new_pos = local_SkipField(buffer, new_pos, end, tag_bytes) + if new_pos == -1: + return pos + pos = new_pos + else: + pos = field_decoder(buffer, new_pos, end, self, field_dict) + return pos + cls._InternalParse = InternalParse -def _HasFieldOrExtension(message, field_or_extension): - """Checks if a message has the specified field or extension set. +def _AddIsInitializedMethod(message_descriptor, cls): + """Adds the IsInitialized and FindInitializationError methods to the + protocol message class.""" - The field or extension specified can be optional, required or repeated. If - it is repeated, this function returns True. Otherwise it checks the has bit - of the field or extension. + required_fields = [field for field in message_descriptor.fields + if field.label == _FieldDescriptor.LABEL_REQUIRED] - Args: - message: Message which contains the target field or extension. - field_or_extension: Field or extension to check. This must be a - FieldDescriptor instance. + def IsInitialized(self, errors=None): + """Checks if all required fields of a message are set. - Returns: - True if the message has a value set for the specified field or extension, - or if the field or extension is repeated. - """ - if field_or_extension.label == _FieldDescriptor.LABEL_REPEATED: - return True - if field_or_extension.is_extension: - return message.HasExtension(field_or_extension) - else: - return message.HasField(field_or_extension.name) + Args: + errors: A list which, if provided, will be populated with the field + paths of all missing required fields. + Returns: + True iff the specified message has all required fields set. + """ -def _IsFieldOrExtensionInitialized(message, field, errors=None): - """Checks if a message field or extension is initialized. + # Performance is critical so we avoid HasField() and ListFields(). - Args: - message: The message which contains the field or extension. - field: Field or extension to check. This must be a FieldDescriptor instance. - errors: Errors will be appended to it, if set to a meaningful value. + for field in required_fields: + if (field not in self._fields or + (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and + not self._fields[field]._is_present_in_parent)): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False - Returns: - True if the field/extension can be considered initialized. - """ - # If the field is required and is not set, it isn't initialized. - if field.label == _FieldDescriptor.LABEL_REQUIRED: - if not _HasFieldOrExtension(message, field): - if errors is not None: - errors.append('Required field %s is not set.' % field.full_name) - return False + for field, value in self._fields.iteritems(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.label == _FieldDescriptor.LABEL_REPEATED: + for element in value: + if not element.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + elif value._is_present_in_parent and not value.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False - # If the field is optional and is not set, or if it - # isn't a submessage then the field is initialized. - if field.label == _FieldDescriptor.LABEL_OPTIONAL: - if not _HasFieldOrExtension(message, field): - return True - if field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE: return True - # The field is set and is either a single or a repeated submessage. - messages = _FieldOrExtensionValues(message, field) - # If all submessages in this field are initialized, the field is - # considered initialized. - for message in messages: - if not _InternalIsInitialized(message, errors): - return False - return True - + cls.IsInitialized = IsInitialized -def _InternalIsInitialized(message, errors=None): - """Checks if all required fields of a message are set. - - Args: - message: The message to check. - errors: If set, initialization errors will be appended to it. + def FindInitializationErrors(self): + """Finds required fields which are not initialized. - Returns: - True iff the specified message has all required fields set. - """ - fields_and_extensions = [] - fields_and_extensions.extend(message.DESCRIPTOR.fields) - fields_and_extensions.extend( - [extension[0] for extension in message.Extensions._ListSetExtensions()]) - for field_or_extension in fields_and_extensions: - if not _IsFieldOrExtensionInitialized(message, field_or_extension, errors): - return False - return True - - -def _AddMergeFromStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - Decoder = decoder.Decoder - def MergeFromString(self, serialized): - decoder = Decoder(serialized) - byte_count = 0 - while not decoder.EndOfStream(): - bytes_read = _DeserializeOneEntity(message_descriptor, self, decoder) - if not bytes_read: - break - byte_count += bytes_read - return byte_count - cls.MergeFromString = MergeFromString - - -def _AddIsInitializedMethod(cls): - """Adds the IsInitialized method to the protocol message class.""" - cls.IsInitialized = _InternalIsInitialized + Returns: + A list of strings. Each string is a path to an uninitialized field from + the top-level message, e.g. "foo.bar[5].baz". + """ + errors = [] # simplify things -def _MergeFieldOrExtension(destination_msg, field, value): - """Merges a specified message field into another message.""" - property_name = _PropertyName(field.name) - is_extension = field.is_extension + for field in required_fields: + if not self.HasField(field.name): + errors.append(field.name) - if not is_extension: - destination = getattr(destination_msg, property_name) - elif (field.label == _FieldDescriptor.LABEL_REPEATED or - field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE): - destination = destination_msg.Extensions[field] + for field, value in self.ListFields(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.is_extension: + name = "(%s)" % field.full_name + else: + name = field.name - # Case 1 - a composite field. - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.label == _FieldDescriptor.LABEL_REPEATED: - for v in value: - destination.add().MergeFrom(v) - else: - destination.MergeFrom(value) - return + if field.label == _FieldDescriptor.LABEL_REPEATED: + for i in xrange(len(value)): + element = value[i] + prefix = "%s[%d]." % (name, i) + sub_errors = element.FindInitializationErrors() + errors += [ prefix + error for error in sub_errors ] + else: + prefix = name + "." + sub_errors = value.FindInitializationErrors() + errors += [ prefix + error for error in sub_errors ] - # Case 2 - a repeated field. - if field.label == _FieldDescriptor.LABEL_REPEATED: - for v in value: - destination.append(v) - return + return errors - # Case 3 - a singular field. - if is_extension: - destination_msg.Extensions[field] = value - else: - setattr(destination_msg, property_name, value) + cls.FindInitializationErrors = FindInitializationErrors def _AddMergeFromMethod(cls): + LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED + CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE + def MergeFrom(self, msg): assert msg is not self - for field in msg.ListFields(): - _MergeFieldOrExtension(self, field[0], field[1]) + self._Modified() + + fields = self._fields + + for field, value in msg._fields.iteritems(): + if field.label == LABEL_REPEATED or field.cpp_type == CPPTYPE_MESSAGE: + field_value = fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + fields[field] = field_value + field_value.MergeFrom(value) + else: + self._fields[field] = value cls.MergeFrom = MergeFrom def _AddMessageMethods(message_descriptor, cls): """Adds implementations of all Message methods to cls.""" _AddListFieldsMethod(message_descriptor, cls) - _AddHasFieldMethod(cls) - _AddClearFieldMethod(cls) - _AddClearExtensionMethod(cls) - _AddClearMethod(cls) - _AddHasExtensionMethod(cls) + _AddHasFieldMethod(message_descriptor, cls) + _AddClearFieldMethod(message_descriptor, cls) + if message_descriptor.is_extendable: + _AddClearExtensionMethod(cls) + _AddHasExtensionMethod(cls) + _AddClearMethod(message_descriptor, cls) _AddEqualsMethod(message_descriptor, cls) _AddStrMethod(message_descriptor, cls) _AddSetListenerMethod(cls) @@ -1304,31 +971,30 @@ def _AddMessageMethods(message_descriptor, cls): _AddSerializeToStringMethod(message_descriptor, cls) _AddSerializePartialToStringMethod(message_descriptor, cls) _AddMergeFromStringMethod(message_descriptor, cls) - _AddIsInitializedMethod(cls) + _AddIsInitializedMethod(message_descriptor, cls) _AddMergeFromMethod(cls) def _AddPrivateHelperMethods(cls): """Adds implementation of private helper methods to cls.""" - def MaybeCallTransitionToNonemptyCallback(self): - """Calls self._listener.TransitionToNonempty() the first time this - method is called. On all subsequent calls, this is a no-op. - """ - if not self._called_transition_to_nonempty: - self._listener.TransitionToNonempty() - self._called_transition_to_nonempty = True - cls._MaybeCallTransitionToNonemptyCallback = ( - MaybeCallTransitionToNonemptyCallback) - - def MarkByteSizeDirty(self): + def Modified(self): """Sets the _cached_byte_size_dirty bit to true, and propagates this to our listener iff this was a state change. """ + + # Note: Some callers check _cached_byte_size_dirty before calling + # _Modified() as an extra optimization. So, if this method is ever + # changed such that it does stuff even when _cached_byte_size_dirty is + # already true, the callers need to be updated. if not self._cached_byte_size_dirty: self._cached_byte_size_dirty = True - self._listener.ByteSizeDirty() - cls._MarkByteSizeDirty = MarkByteSizeDirty + self._listener_for_children.dirty = True + self._is_present_in_parent = True + self._listener.Modified() + + cls._Modified = Modified + cls.SetInParent = Modified class _Listener(object): @@ -1338,22 +1004,17 @@ class _Listener(object): In order to support semantics like: - foo.bar.baz = 23 + foo.bar.baz.qux = 23 assert foo.HasField('bar') ...child objects must have back references to their parents. This helper class is at the heart of this support. """ - def __init__(self, parent_message, has_field_name): + def __init__(self, parent_message): """Args: - parent_message: The message whose _MaybeCallTransitionToNonemptyCallback() - and _MarkByteSizeDirty() methods we should call when we receive - TransitionToNonempty() and ByteSizeDirty() messages. - has_field_name: The name of the "has" field that we should set in - the parent message when we receive a TransitionToNonempty message, - or None if there's no "has" field to set. (This will be the case - for child objects in "repeated" fields). + parent_message: The message whose _Modified() method we should call when + we receive Modified() messages. """ # This listener establishes a back reference from a child (contained) object # to its parent (containing) object. We make this a weak reference to avoid @@ -1363,36 +1024,27 @@ class _Listener(object): self._parent_message_weakref = parent_message else: self._parent_message_weakref = weakref.proxy(parent_message) - self._has_field_name = has_field_name - def TransitionToNonempty(self): + # As an optimization, we also indicate directly on the listener whether + # or not the parent message is dirty. This way we can avoid traversing + # up the tree in the common case. + self.dirty = False + + def Modified(self): + if self.dirty: + return try: - if self._has_field_name is not None: - setattr(self._parent_message_weakref, self._has_field_name, True) # Propagate the signal to our parents iff this is the first field set. - self._parent_message_weakref._MaybeCallTransitionToNonemptyCallback() + self._parent_message_weakref._Modified() except ReferenceError: # We can get here if a client has kept a reference to a child object, # and is now setting a field on it, but the child's parent has been # garbage-collected. This is not an error. pass - def ByteSizeDirty(self): - try: - self._parent_message_weakref._MarkByteSizeDirty() - except ReferenceError: - # Same as above. - pass - # TODO(robinson): Move elsewhere? This file is getting pretty ridiculous... # TODO(robinson): Unify error handling of "unknown extension" crap. -# TODO(robinson): There's so much similarity between the way that -# extensions behave and the way that normal fields behave that it would -# be really nice to unify more code. It's not immediately obvious -# how to do this, though, and I'd rather get the full functionality -# implemented (and, crucially, get all the tests and specs fleshed out -# and passing), and then come back to this thorny unification problem. # TODO(robinson): Support iteritems()-style iteration over all # extensions with the "has" bits turned on? class _ExtensionDict(object): @@ -1404,250 +1056,85 @@ class _ExtensionDict(object): FieldDescriptors. """ - class _ExtensionListener(object): + def __init__(self, extended_message): + """extended_message: Message instance for which we are the Extensions dict. + """ - """Adapts an _ExtensionDict to behave as a MessageListener.""" + self._extended_message = extended_message - def __init__(self, extension_dict, handle_id): - self._extension_dict = extension_dict - self._handle_id = handle_id + def __getitem__(self, extension_handle): + """Returns the current value of the given extension handle.""" - def TransitionToNonempty(self): - self._extension_dict._SubmessageTransitionedToNonempty(self._handle_id) + _VerifyExtensionHandle(self._extended_message, extension_handle) - def ByteSizeDirty(self): - self._extension_dict._SubmessageByteSizeBecameDirty() + result = self._extended_message._fields.get(extension_handle) + if result is not None: + return result - # TODO(robinson): Somewhere, we need to blow up if people - # try to register two extensions with the same field number. - # (And we need a test for this of course). + if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: + result = extension_handle._default_constructor(self._extended_message) + elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + result = extension_handle.message_type._concrete_class() + try: + result._SetListener(self._extended_message._listener_for_children) + except ReferenceError: + pass + else: + # Singular scalar -- just return the default without inserting into the + # dict. + return extension_handle.default_value - def __init__(self, extended_message, known_extensions): - """extended_message: Message instance for which we are the Extensions dict. - known_extensions: Iterable of known extension handles. - These must be FieldDescriptors. - """ - # We keep a weak reference to extended_message, since - # it has a reference to this instance in turn. - self._extended_message = weakref.proxy(extended_message) - # We make a deep copy of known_extensions to avoid any - # thread-safety concerns, since the argument passed in - # is the global (class-level) dict of known extensions for - # this type of message, which could be modified at any time - # via a RegisterExtension() call. - # - # This dict maps from handle id to handle (a FieldDescriptor). - # - # XXX - # TODO(robinson): This isn't good enough. The client could - # instantiate an object in module A, then afterward import - # module B and pass the instance to B.Foo(). If B imports - # an extender of this proto and then tries to use it, B - # will get a KeyError, even though the extension *is* registered - # at the time of use. - # XXX - self._known_extensions = dict((id(e), e) for e in known_extensions) - # Read lock around self._values, which may be modified by multiple - # concurrent readers in the conceptually "const" __getitem__ method. - # So, we grab this lock in every "read-only" method to ensure - # that concurrent read access is safe without external locking. - self._lock = threading.Lock() - # Maps from extension handle ID to current value of that extension. - self._values = {} - # Maps from extension handle ID to a boolean "has" bit, but only - # for non-repeated extension fields. - keys = (id for id, extension in self._known_extensions.iteritems() - if extension.label != _FieldDescriptor.LABEL_REPEATED) - self._has_bits = dict.fromkeys(keys, False) - - self._extensions_by_number = dict( - (f.number, f) for f in self._known_extensions.itervalues()) - - self._extensions_by_name = {} - for extension in self._known_extensions.itervalues(): - if (extension.containing_type.GetOptions().message_set_wire_format and - extension.type == descriptor_mod.FieldDescriptor.TYPE_MESSAGE and - extension.message_type == extension.extension_scope and - extension.label == descriptor_mod.FieldDescriptor.LABEL_OPTIONAL): - extension_name = extension.message_type.full_name - else: - extension_name = extension.full_name - self._extensions_by_name[extension_name] = extension + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + result = self._extended_message._fields.setdefault( + extension_handle, result) - def __getitem__(self, extension_handle): - """Returns the current value of the given extension handle.""" - # We don't care as much about keeping critical sections short in the - # extension support, since it's presumably much less of a common case. - self._lock.acquire() - try: - handle_id = id(extension_handle) - if handle_id not in self._known_extensions: - raise KeyError('Extension not known to this class') - if handle_id not in self._values: - self._AddMissingHandle(extension_handle, handle_id) - return self._values[handle_id] - finally: - self._lock.release() + return result def __eq__(self, other): - # We have to grab read locks since we're accessing _values - # in a "const" method. See the comment in the constructor. - if self is other: - return True - self._lock.acquire() - try: - other._lock.acquire() - try: - if self._has_bits != other._has_bits: - return False - # If there's a "has" bit, then only compare values where it is true. - for k, v in self._values.iteritems(): - if self._has_bits.get(k, False) and v != other._values[k]: - return False - return True - finally: - other._lock.release() - finally: - self._lock.release() + if not isinstance(other, self.__class__): + return False + + my_fields = self._extended_message.ListFields() + other_fields = other._extended_message.ListFields() + + # Get rid of non-extension fields. + my_fields = [ field for field in my_fields if field.is_extension ] + other_fields = [ field for field in other_fields if field.is_extension ] + + return my_fields == other_fields def __ne__(self, other): return not self == other # Note that this is only meaningful for non-repeated, scalar extension - # fields. Note also that we may have to call - # MaybeCallTransitionToNonemptyCallback() when we do successfully set a field - # this way, to set any necssary "has" bits in the ancestors of the extended - # message. + # fields. Note also that we may have to call _Modified() when we do + # successfully set a field this way, to set any necssary "has" bits in the + # ancestors of the extended message. def __setitem__(self, extension_handle, value): """If extension_handle specifies a non-repeated, scalar extension field, sets the value of that field. """ - handle_id = id(extension_handle) - if handle_id not in self._known_extensions: - raise KeyError('Extension not known to this class') - field = extension_handle # Just shorten the name. - if (field.label == _FieldDescriptor.LABEL_OPTIONAL - and field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE): - # It's slightly wasteful to lookup the type checker each time, - # but we expect this to be a vanishingly uncommon case anyway. - type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) - type_checker.CheckValue(value) - self._values[handle_id] = value - self._has_bits[handle_id] = True - self._extended_message._MarkByteSizeDirty() - self._extended_message._MaybeCallTransitionToNonemptyCallback() - else: - raise TypeError('Extension is repeated and/or a composite type.') - - def _AddMissingHandle(self, extension_handle, handle_id): - """Helper internal to ExtensionDict.""" - # Special handling for non-repeated message extensions, which (like - # normal fields of this kind) are initialized lazily. - # REQUIRES: _lock already held. - cpp_type = extension_handle.cpp_type - label = extension_handle.label - if (cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE - and label != _FieldDescriptor.LABEL_REPEATED): - self._AddMissingNonRepeatedCompositeHandle(extension_handle, handle_id) - else: - self._values[handle_id] = _DefaultValueForField( - self._extended_message, extension_handle) - - def _AddMissingNonRepeatedCompositeHandle(self, extension_handle, handle_id): - """Helper internal to ExtensionDict.""" - # REQUIRES: _lock already held. - value = extension_handle.message_type._concrete_class() - value._SetListener(_ExtensionDict._ExtensionListener(self, handle_id)) - self._values[handle_id] = value - - def _SubmessageTransitionedToNonempty(self, handle_id): - """Called when a submessage with a given handle id first transitions to - being nonempty. Called by _ExtensionListener. - """ - assert handle_id in self._has_bits - self._has_bits[handle_id] = True - self._extended_message._MaybeCallTransitionToNonemptyCallback() - def _SubmessageByteSizeBecameDirty(self): - """Called whenever a submessage's cached byte size becomes invalid - (goes from being "clean" to being "dirty"). Called by _ExtensionListener. - """ - self._extended_message._MarkByteSizeDirty() - - # We may wish to widen the public interface of Message.Extensions - # to expose some of this private functionality in the future. - # For now, we make all this functionality module-private and just - # implement what we need for serialization/deserialization, - # HasField()/ClearField(), etc. - - def _HasExtension(self, extension_handle): - """Method for internal use by this module. - Returns true iff we "have" this extension in the sense of the - "has" bit being set. - """ - handle_id = id(extension_handle) - # Note that this is different from the other checks. - if handle_id not in self._has_bits: - raise KeyError('Extension not known to this class, or is repeated field.') - return self._has_bits[handle_id] - - # Intentionally pretty similar to ClearField() above. - def _ClearExtension(self, extension_handle): - """Method for internal use by this module. - Clears the specified extension, unsetting its "has" bit. - """ - handle_id = id(extension_handle) - if handle_id not in self._known_extensions: - raise KeyError('Extension not known to this class') - default_value = _DefaultValueForField(self._extended_message, - extension_handle) - if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: - self._extended_message._MarkByteSizeDirty() - else: - cpp_type = extension_handle.cpp_type - if cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if handle_id in self._values: - # Future modifications to this object shouldn't set any - # "has" bits here. - self._values[handle_id]._SetListener(None) - if self._has_bits[handle_id]: - self._has_bits[handle_id] = False - self._extended_message._MarkByteSizeDirty() - if handle_id in self._values: - del self._values[handle_id] - - def _ListSetExtensions(self): - """Method for internal use by this module. - - Returns an sequence of all extensions that are currently "set" - in this extension dict. A "set" extension is a repeated extension, - or a non-repeated extension with its "has" bit set. - - The returned sequence contains (field_descriptor, value) pairs, - where value is the current value of the extension with the given - field descriptor. - - The sequence values are in arbitrary order. - """ - self._lock.acquire() # Read-only methods must lock around self._values. - try: - set_extensions = [] - for handle_id, value in self._values.iteritems(): - handle = self._known_extensions[handle_id] - if (handle.label == _FieldDescriptor.LABEL_REPEATED - or self._has_bits[handle_id]): - set_extensions.append((handle, value)) - return set_extensions - finally: - self._lock.release() - - def _AllExtensionsByNumber(self): - """Method for internal use by this module. - - Returns: A dict mapping field_number to (handle, field_descriptor), - for *all* registered extensions for this dict. - """ - return self._extensions_by_number + _VerifyExtensionHandle(self._extended_message, extension_handle) + + if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or + extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE): + raise TypeError( + 'Cannot assign to extension "%s" because it is a repeated or ' + 'composite type.' % extension_handle.full_name) + + # It's slightly wasteful to lookup the type checker each time, + # but we expect this to be a vanishingly uncommon case anyway. + type_checker = type_checkers.GetTypeChecker( + extension_handle.cpp_type, extension_handle.type) + type_checker.CheckValue(value) + self._extended_message._fields[extension_handle] = value + self._extended_message._Modified() def _FindExtensionByName(self, name): """Tries to find a known extension with the specified name. @@ -1658,4 +1145,4 @@ class _ExtensionDict(object): Returns: Extension field descriptor. """ - return self._extensions_by_name.get(name, None) + return self._extended_message._extensions_by_name.get(name, None) diff --git a/python/google/protobuf/service.py b/python/google/protobuf/service.py index dd136c9..180b70e 100755 --- a/python/google/protobuf/service.py +++ b/python/google/protobuf/service.py @@ -28,12 +28,16 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Declares the RPC service interfaces. +"""DEPRECATED: Declares the RPC service interfaces. This module declares the abstract interfaces underlying proto2 RPC services. These are intended to be independent of any particular RPC implementation, so that proto2 services can be used on top of a variety -of implementations. +of implementations. Starting with version 2.3.0, RPC implementations should +not try to build on these, but should instead provide code generator plugins +which generate code specific to the particular RPC implementation. This way +the generated code can be more appropriate for the implementation in use +and can avoid unnecessary layers of indirection. """ __author__ = 'petar@google.com (Petar Petrov)' diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index 1cddce6..cc6ac90 100755 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -43,6 +43,12 @@ __all__ = [ 'MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue', 'Merge' ] +# Infinity and NaN are not explicitly supported by Python pre-2.6, and +# float('inf') does not work on Windows (pre-2.6). +_INFINITY = 1e10000 # overflows, thus will actually be infinity. +_NAN = _INFINITY * 0 + + class ParseError(Exception): """Thrown in case of ASCII parsing error.""" @@ -149,6 +155,10 @@ def _MergeField(tokenizer, message): name.append(tokenizer.ConsumeIdentifier()) name = '.'.join(name) + if not message_descriptor.is_extendable: + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" does not have extensions.' % + message_descriptor.full_name) field = message.Extensions._FindExtensionByName(name) if not field: raise tokenizer.ParseErrorPreviousToken( @@ -198,6 +208,7 @@ def _MergeField(tokenizer, message): sub_message = message.Extensions[field] else: sub_message = getattr(message, field.name) + sub_message.SetInParent() while not tokenizer.TryConsume(end_token): if tokenizer.AtEnd(): @@ -293,7 +304,7 @@ class _Tokenizer(object): '[a-zA-Z_][0-9a-zA-Z_+-]*|' # an identifier '[0-9+-][0-9a-zA-Z_.+-]*|' # a number '\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|' # a double-quoted string - '\'([^\"\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string + '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string _IDENTIFIER = re.compile('\w+') _INTEGER_CHECKERS = [type_checkers.Uint32ValueChecker(), type_checkers.Int32ValueChecker(), @@ -473,12 +484,12 @@ class _Tokenizer(object): if re.match(self._FLOAT_INFINITY, text): self.NextToken() if text.startswith('-'): - return float('-inf') - return float('inf') + return -_INFINITY + return _INFINITY if re.match(self._FLOAT_NAN, text): self.NextToken() - return float('nan') + return _NAN try: result = float(text) @@ -525,6 +536,18 @@ class _Tokenizer(object): Raises: ParseError: If a byte array value couldn't be consumed. """ + list = [self._ConsumeSingleByteString()] + while len(self.token) > 0 and self.token[0] in ('\'', '"'): + list.append(self._ConsumeSingleByteString()) + return "".join(list) + + def _ConsumeSingleByteString(self): + """Consume one token of a string literal. + + String literals (whether bytes or text) can come in multiple adjacent + tokens which are automatically concatenated, like in C or Python. This + method only consumes one token. + """ text = self.token if len(text) < 1 or text[0] not in ('\'', '"'): raise self._ParseError('Exptected string.') diff --git a/python/setup.py b/python/setup.py index d2997da..7242dae 100755 --- a/python/setup.py +++ b/python/setup.py @@ -58,16 +58,13 @@ def MakeTestSuite(): generate_proto("../src/google/protobuf/unittest.proto") generate_proto("../src/google/protobuf/unittest_import.proto") generate_proto("../src/google/protobuf/unittest_mset.proto") + generate_proto("../src/google/protobuf/unittest_no_generic_services.proto") generate_proto("google/protobuf/internal/more_extensions.proto") generate_proto("google/protobuf/internal/more_messages.proto") import unittest import google.protobuf.internal.generator_test as generator_test - import google.protobuf.internal.decoder_test as decoder_test import google.protobuf.internal.descriptor_test as descriptor_test - import google.protobuf.internal.encoder_test as encoder_test - import google.protobuf.internal.input_stream_test as input_stream_test - import google.protobuf.internal.output_stream_test as output_stream_test import google.protobuf.internal.reflection_test as reflection_test import google.protobuf.internal.service_reflection_test \ as service_reflection_test @@ -77,11 +74,7 @@ def MakeTestSuite(): loader = unittest.defaultTestLoader suite = unittest.TestSuite() for test in [ generator_test, - decoder_test, descriptor_test, - encoder_test, - input_stream_test, - output_stream_test, reflection_test, service_reflection_test, text_format_test, @@ -105,7 +98,7 @@ if __name__ == '__main__': generate_proto("../src/google/protobuf/descriptor.proto") setup(name = 'protobuf', - version = '2.2.0', + version = '2.3.0', packages = [ 'google' ], namespace_packages = [ 'google' ], test_suite = 'setup.MakeTestSuite', @@ -114,9 +107,7 @@ if __name__ == '__main__': 'google.protobuf.internal.containers', 'google.protobuf.internal.decoder', 'google.protobuf.internal.encoder', - 'google.protobuf.internal.input_stream', 'google.protobuf.internal.message_listener', - 'google.protobuf.internal.output_stream', 'google.protobuf.internal.type_checkers', 'google.protobuf.internal.wire_format', 'google.protobuf.descriptor', diff --git a/src/Makefile.am b/src/Makefile.am index 11f05f6..35f5c0c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,13 +24,15 @@ AM_LDFLAGS = $(PTHREAD_CFLAGS) # If I say "dist_include_DATA", automake complains that $(includedir) is not # a "legitimate" directory for DATA. Screw you, automake. protodir = $(includedir) -nobase_dist_proto_DATA = google/protobuf/descriptor.proto +nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ + google/protobuf/compiler/plugin.proto # Not sure why these don't get cleaned automatically. clean-local: rm -f *.loT -CLEANFILES = $(protoc_outputs) unittest_proto_middleman +CLEANFILES = $(protoc_outputs) unittest_proto_middleman \ + testzip.jar testzip.list testzip.proto testzip.zip MAINTAINERCLEANFILES = \ Makefile.in @@ -66,15 +68,16 @@ nobase_include_HEADERS = \ google/protobuf/compiler/command_line_interface.h \ google/protobuf/compiler/importer.h \ google/protobuf/compiler/parser.h \ + google/protobuf/compiler/plugin.h \ + google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/cpp/cpp_generator.h \ google/protobuf/compiler/java/java_generator.h \ - google/protobuf/compiler/javamicro/javamicro_generator.h \ google/protobuf/compiler/python/python_generator.h lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_lite_la_LDFLAGS = -version-info 5:0:0 +libprotobuf_lite_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/common.cc \ google/protobuf/stubs/once.cc \ @@ -88,11 +91,12 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/repeated_field.cc \ google/protobuf/wire_format_lite.cc \ google/protobuf/io/coded_stream.cc \ + google/protobuf/io/coded_stream_inl.h \ google/protobuf/io/zero_copy_stream.cc \ google/protobuf/io/zero_copy_stream_impl_lite.cc libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 5:0:0 +libprotobuf_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined libprotobuf_la_SOURCES = \ $(libprotobuf_lite_la_SOURCES) \ google/protobuf/stubs/strutil.cc \ @@ -120,10 +124,16 @@ libprotobuf_la_SOURCES = \ google/protobuf/compiler/parser.cc libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la -libprotoc_la_LDFLAGS = -version-info 5:0:0 +libprotoc_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ + google/protobuf/compiler/plugin.cc \ + google/protobuf/compiler/plugin.pb.cc \ + google/protobuf/compiler/subprocess.cc \ + google/protobuf/compiler/subprocess.h \ + google/protobuf/compiler/zip_writer.cc \ + google/protobuf/compiler/zip_writer.h \ google/protobuf/compiler/cpp/cpp_enum.cc \ google/protobuf/compiler/cpp/cpp_enum.h \ google/protobuf/compiler/cpp/cpp_enum_field.cc \ @@ -168,23 +178,6 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_primitive_field.h \ google/protobuf/compiler/java/java_service.cc \ google/protobuf/compiler/java/java_service.h \ - google/protobuf/compiler/javamicro/javamicro_enum.cc \ - google/protobuf/compiler/javamicro/javamicro_enum.h \ - google/protobuf/compiler/javamicro/javamicro_enum_field.cc \ - google/protobuf/compiler/javamicro/javamicro_enum_field.h \ - google/protobuf/compiler/javamicro/javamicro_field.cc \ - google/protobuf/compiler/javamicro/javamicro_field.h \ - google/protobuf/compiler/javamicro/javamicro_file.cc \ - google/protobuf/compiler/javamicro/javamicro_file.h \ - google/protobuf/compiler/javamicro/javamicro_generator.cc \ - google/protobuf/compiler/javamicro/javamicro_helpers.cc \ - google/protobuf/compiler/javamicro/javamicro_helpers.h \ - google/protobuf/compiler/javamicro/javamicro_message.cc \ - google/protobuf/compiler/javamicro/javamicro_message.h \ - google/protobuf/compiler/javamicro/javamicro_message_field.cc\ - google/protobuf/compiler/javamicro/javamicro_message_field.h \ - google/protobuf/compiler/javamicro/javamicro_primitive_field.cc\ - google/protobuf/compiler/javamicro/javamicro_primitive_field.h\ google/protobuf/compiler/python/python_generator.cc bin_PROGRAMS = protoc @@ -204,6 +197,7 @@ protoc_inputs = \ google/protobuf/unittest_lite.proto \ google/protobuf/unittest_import_lite.proto \ google/protobuf/unittest_lite_imports_nonlite.proto \ + google/protobuf/unittest_no_generic_services.proto \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto EXTRA_DIST = \ @@ -218,6 +212,7 @@ EXTRA_DIST = \ google/protobuf/package_info.h \ google/protobuf/io/package_info.h \ google/protobuf/compiler/package_info.h \ + google/protobuf/compiler/zip_output_unittest.sh \ google/protobuf/unittest_enormous_descriptor.proto protoc_lite_outputs = \ @@ -244,6 +239,8 @@ protoc_outputs = \ google/protobuf/unittest_custom_options.pb.h \ google/protobuf/unittest_lite_imports_nonlite.pb.cc \ google/protobuf/unittest_lite_imports_nonlite.pb.h \ + google/protobuf/unittest_no_generic_services.pb.cc \ + google/protobuf/unittest_no_generic_services.pb.h \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h @@ -252,23 +249,16 @@ BUILT_SOURCES = $(protoc_outputs) if USE_EXTERNAL_PROTOC unittest_proto_middleman: $(protoc_inputs) - $(PROTOC) -I$(srcdir) --cpp_out=. $(protoc_inputs) + $(PROTOC) -I$(srcdir) --cpp_out=. $^ touch unittest_proto_middleman else -# This rule is a little weird. The first prereq is the protoc executable -# and the rest are its inputs. Therefore, $^ -- which expands to the -# list of prereqs -- is actually a valid command. We have to place "./" in -# front of it in case protoc is in the current directory. protoc allows -# flags to appear after input file names, so we happily stick the flags on -# the end. -# -# For reference, if we didn't have to worry about VPATH (i.e., building from -# a directory other than the package root), we could have just written this: -# ./protoc$(EXEEXT) -I$(srcdir) --cpp_out=. $(protoc_inputs) +# 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. unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs) - ./$^ -I$(srcdir) --cpp_out=. + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) ) touch unittest_proto_middleman endif @@ -283,7 +273,8 @@ COMMON_TEST_SOURCES = \ google/protobuf/testing/file.cc \ google/protobuf/testing/file.h -check_PROGRAMS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test $(GZCHECKPROGRAMS) +check_PROGRAMS = protoc protobuf-test protobuf-lazy-descriptor-test \ + protobuf-lite-test test_plugin $(GZCHECKPROGRAMS) protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \ $(top_builddir)/gtest/lib/libgtest.la \ $(top_builddir)/gtest/lib/libgtest_main.la @@ -315,9 +306,14 @@ protobuf_test_SOURCES = \ google/protobuf/io/zero_copy_stream_unittest.cc \ google/protobuf/compiler/command_line_interface_unittest.cc \ google/protobuf/compiler/importer_unittest.cc \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/compiler/mock_code_generator.h \ google/protobuf/compiler/parser_unittest.cc \ google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ google/protobuf/compiler/cpp/cpp_unittest.cc \ + google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ + google/protobuf/compiler/java/java_plugin_unittest.cc \ + google/protobuf/compiler/python/python_plugin_unittest.cc \ $(COMMON_TEST_SOURCES) nodist_protobuf_test_SOURCES = $(protoc_outputs) @@ -343,6 +339,17 @@ protobuf_lite_test_SOURCES = \ google/protobuf/test_util_lite.h nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs) +# Test plugin binary. +test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \ + $(top_builddir)/gtest/lib/libgtest.la +test_plugin_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include +test_plugin_SOURCES = \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/testing/file.cc \ + google/protobuf/testing/file.h \ + google/protobuf/compiler/test_plugin.cc + if HAVE_ZLIB zcgzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la zcgzip_SOURCES = google/protobuf/testing/zcgzip.cc @@ -351,4 +358,5 @@ zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc endif -TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test $(GZTESTS) +TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \ + google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS) diff --git a/src/Makefile.in b/src/Makefile.in index 1de053d..daf81af 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -37,11 +37,14 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = protoc$(EXEEXT) -check_PROGRAMS = protobuf-test$(EXEEXT) \ +check_PROGRAMS = protoc$(EXEEXT) protobuf-test$(EXEEXT) \ protobuf-lazy-descriptor-test$(EXEEXT) \ - protobuf-lite-test$(EXEEXT) $(am__EXEEXT_1) + protobuf-lite-test$(EXEEXT) test_plugin$(EXEEXT) \ + $(am__EXEEXT_1) TESTS = protobuf-test$(EXEEXT) protobuf-lazy-descriptor-test$(EXEEXT) \ - protobuf-lite-test$(EXEEXT) $(am__EXEEXT_2) + protobuf-lite-test$(EXEEXT) \ + google/protobuf/compiler/zip_output_unittest.sh \ + $(am__EXEEXT_2) subdir = src DIST_COMMON = $(am__nobase_include_HEADERS_DIST) \ $(nobase_dist_proto_DATA) $(srcdir)/Makefile.am \ @@ -96,17 +99,14 @@ libprotobuf_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(CXXFLAGS) $(libprotobuf_la_LDFLAGS) $(LDFLAGS) -o $@ libprotoc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la am_libprotoc_la_OBJECTS = code_generator.lo command_line_interface.lo \ - cpp_enum.lo cpp_enum_field.lo cpp_extension.lo cpp_field.lo \ - cpp_file.lo cpp_generator.lo cpp_helpers.lo cpp_message.lo \ + plugin.lo plugin.pb.lo subprocess.lo zip_writer.lo cpp_enum.lo \ + cpp_enum_field.lo cpp_extension.lo cpp_field.lo cpp_file.lo \ + cpp_generator.lo cpp_helpers.lo cpp_message.lo \ cpp_message_field.lo cpp_primitive_field.lo cpp_service.lo \ cpp_string_field.lo java_enum.lo java_enum_field.lo \ java_extension.lo java_field.lo java_file.lo java_generator.lo \ java_helpers.lo java_message.lo java_message_field.lo \ - java_primitive_field.lo java_service.lo javamicro_enum.lo \ - javamicro_enum_field.lo javamicro_field.lo javamicro_file.lo \ - javamicro_generator.lo javamicro_helpers.lo \ - javamicro_message.lo javamicro_message_field.lo \ - javamicro_primitive_field.lo python_generator.lo + java_primitive_field.lo java_service.lo python_generator.lo libprotoc_la_OBJECTS = $(am_libprotoc_la_OBJECTS) libprotoc_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ @@ -132,6 +132,7 @@ am__objects_4 = $(am__objects_3) \ protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT) \ protobuf_lazy_descriptor_test-unittest_custom_options.pb.$(OBJEXT) \ protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \ + protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.$(OBJEXT) \ protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT) nodist_protobuf_lazy_descriptor_test_OBJECTS = $(am__objects_4) protobuf_lazy_descriptor_test_OBJECTS = \ @@ -182,9 +183,14 @@ am_protobuf_test_OBJECTS = protobuf_test-common_unittest.$(OBJEXT) \ protobuf_test-zero_copy_stream_unittest.$(OBJEXT) \ protobuf_test-command_line_interface_unittest.$(OBJEXT) \ protobuf_test-importer_unittest.$(OBJEXT) \ + protobuf_test-mock_code_generator.$(OBJEXT) \ protobuf_test-parser_unittest.$(OBJEXT) \ protobuf_test-cpp_bootstrap_unittest.$(OBJEXT) \ - protobuf_test-cpp_unittest.$(OBJEXT) $(am__objects_6) + protobuf_test-cpp_unittest.$(OBJEXT) \ + protobuf_test-cpp_plugin_unittest.$(OBJEXT) \ + protobuf_test-java_plugin_unittest.$(OBJEXT) \ + protobuf_test-python_plugin_unittest.$(OBJEXT) \ + $(am__objects_6) am__objects_7 = protobuf_test-unittest_lite.pb.$(OBJEXT) \ protobuf_test-unittest_import_lite.pb.$(OBJEXT) am__objects_8 = $(am__objects_7) protobuf_test-unittest.pb.$(OBJEXT) \ @@ -195,6 +201,7 @@ am__objects_8 = $(am__objects_7) protobuf_test-unittest.pb.$(OBJEXT) \ protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT) \ protobuf_test-unittest_custom_options.pb.$(OBJEXT) \ protobuf_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \ + protobuf_test-unittest_no_generic_services.pb.$(OBJEXT) \ protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT) nodist_protobuf_test_OBJECTS = $(am__objects_8) protobuf_test_OBJECTS = $(am_protobuf_test_OBJECTS) \ @@ -209,6 +216,11 @@ am_protoc_OBJECTS = main.$(OBJEXT) protoc_OBJECTS = $(am_protoc_OBJECTS) protoc_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \ libprotoc.la +am_test_plugin_OBJECTS = test_plugin-mock_code_generator.$(OBJEXT) \ + test_plugin-file.$(OBJEXT) test_plugin-test_plugin.$(OBJEXT) +test_plugin_OBJECTS = $(am_test_plugin_OBJECTS) +test_plugin_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \ + libprotoc.la $(top_builddir)/gtest/lib/libgtest.la am__zcgunzip_SOURCES_DIST = google/protobuf/testing/zcgunzip.cc @HAVE_ZLIB_TRUE@am_zcgunzip_OBJECTS = zcgunzip.$(OBJEXT) zcgunzip_OBJECTS = $(am_zcgunzip_OBJECTS) @@ -247,13 +259,13 @@ SOURCES = $(libprotobuf_lite_la_SOURCES) $(libprotobuf_la_SOURCES) \ $(protobuf_lite_test_SOURCES) \ $(nodist_protobuf_lite_test_SOURCES) $(protobuf_test_SOURCES) \ $(nodist_protobuf_test_SOURCES) $(protoc_SOURCES) \ - $(zcgunzip_SOURCES) $(zcgzip_SOURCES) + $(test_plugin_SOURCES) $(zcgunzip_SOURCES) $(zcgzip_SOURCES) DIST_SOURCES = $(libprotobuf_lite_la_SOURCES) \ $(libprotobuf_la_SOURCES) $(libprotoc_la_SOURCES) \ $(protobuf_lazy_descriptor_test_SOURCES) \ $(protobuf_lite_test_SOURCES) $(protobuf_test_SOURCES) \ - $(protoc_SOURCES) $(am__zcgunzip_SOURCES_DIST) \ - $(am__zcgzip_SOURCES_DIST) + $(protoc_SOURCES) $(test_plugin_SOURCES) \ + $(am__zcgunzip_SOURCES_DIST) $(am__zcgzip_SOURCES_DIST) nobase_dist_protoDATA_INSTALL = $(install_sh_DATA) DATA = $(nobase_dist_proto_DATA) am__nobase_include_HEADERS_DIST = google/protobuf/stubs/common.h \ @@ -282,9 +294,10 @@ am__nobase_include_HEADERS_DIST = google/protobuf/stubs/common.h \ google/protobuf/compiler/command_line_interface.h \ google/protobuf/compiler/importer.h \ google/protobuf/compiler/parser.h \ + google/protobuf/compiler/plugin.h \ + google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/cpp/cpp_generator.h \ google/protobuf/compiler/java/java_generator.h \ - google/protobuf/compiler/javamicro/javamicro_generator.h \ google/protobuf/compiler/python/python_generator.h nobase_includeHEADERS_INSTALL = $(install_sh_DATA) HEADERS = $(nobase_include_HEADERS) @@ -434,8 +447,12 @@ AM_LDFLAGS = $(PTHREAD_CFLAGS) # If I say "dist_include_DATA", automake complains that $(includedir) is not # a "legitimate" directory for DATA. Screw you, automake. protodir = $(includedir) -nobase_dist_proto_DATA = google/protobuf/descriptor.proto -CLEANFILES = $(protoc_outputs) unittest_proto_middleman +nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ + google/protobuf/compiler/plugin.proto + +CLEANFILES = $(protoc_outputs) unittest_proto_middleman \ + testzip.jar testzip.list testzip.proto testzip.zip + MAINTAINERCLEANFILES = \ Makefile.in @@ -470,14 +487,15 @@ nobase_include_HEADERS = \ google/protobuf/compiler/command_line_interface.h \ google/protobuf/compiler/importer.h \ google/protobuf/compiler/parser.h \ + google/protobuf/compiler/plugin.h \ + google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/cpp/cpp_generator.h \ google/protobuf/compiler/java/java_generator.h \ - google/protobuf/compiler/javamicro/javamicro_generator.h \ google/protobuf/compiler/python/python_generator.h lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_lite_la_LDFLAGS = -version-info 5:0:0 +libprotobuf_lite_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/common.cc \ google/protobuf/stubs/once.cc \ @@ -491,11 +509,12 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/repeated_field.cc \ google/protobuf/wire_format_lite.cc \ google/protobuf/io/coded_stream.cc \ + google/protobuf/io/coded_stream_inl.h \ google/protobuf/io/zero_copy_stream.cc \ google/protobuf/io/zero_copy_stream_impl_lite.cc libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 5:0:0 +libprotobuf_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined libprotobuf_la_SOURCES = \ $(libprotobuf_lite_la_SOURCES) \ google/protobuf/stubs/strutil.cc \ @@ -523,10 +542,16 @@ libprotobuf_la_SOURCES = \ google/protobuf/compiler/parser.cc libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la -libprotoc_la_LDFLAGS = -version-info 5:0:0 +libprotoc_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ + google/protobuf/compiler/plugin.cc \ + google/protobuf/compiler/plugin.pb.cc \ + google/protobuf/compiler/subprocess.cc \ + google/protobuf/compiler/subprocess.h \ + google/protobuf/compiler/zip_writer.cc \ + google/protobuf/compiler/zip_writer.h \ google/protobuf/compiler/cpp/cpp_enum.cc \ google/protobuf/compiler/cpp/cpp_enum.h \ google/protobuf/compiler/cpp/cpp_enum_field.cc \ @@ -571,23 +596,6 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_primitive_field.h \ google/protobuf/compiler/java/java_service.cc \ google/protobuf/compiler/java/java_service.h \ - google/protobuf/compiler/javamicro/javamicro_enum.cc \ - google/protobuf/compiler/javamicro/javamicro_enum.h \ - google/protobuf/compiler/javamicro/javamicro_enum_field.cc \ - google/protobuf/compiler/javamicro/javamicro_enum_field.h \ - google/protobuf/compiler/javamicro/javamicro_field.cc \ - google/protobuf/compiler/javamicro/javamicro_field.h \ - google/protobuf/compiler/javamicro/javamicro_file.cc \ - google/protobuf/compiler/javamicro/javamicro_file.h \ - google/protobuf/compiler/javamicro/javamicro_generator.cc \ - google/protobuf/compiler/javamicro/javamicro_helpers.cc \ - google/protobuf/compiler/javamicro/javamicro_helpers.h \ - google/protobuf/compiler/javamicro/javamicro_message.cc \ - google/protobuf/compiler/javamicro/javamicro_message.h \ - google/protobuf/compiler/javamicro/javamicro_message_field.cc\ - google/protobuf/compiler/javamicro/javamicro_message_field.h \ - google/protobuf/compiler/javamicro/javamicro_primitive_field.cc\ - google/protobuf/compiler/javamicro/javamicro_primitive_field.h\ google/protobuf/compiler/python/python_generator.cc protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la @@ -605,6 +613,7 @@ protoc_inputs = \ google/protobuf/unittest_lite.proto \ google/protobuf/unittest_import_lite.proto \ google/protobuf/unittest_lite_imports_nonlite.proto \ + google/protobuf/unittest_no_generic_services.proto \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto EXTRA_DIST = \ @@ -619,6 +628,7 @@ EXTRA_DIST = \ google/protobuf/package_info.h \ google/protobuf/io/package_info.h \ google/protobuf/compiler/package_info.h \ + google/protobuf/compiler/zip_output_unittest.sh \ google/protobuf/unittest_enormous_descriptor.proto protoc_lite_outputs = \ @@ -645,6 +655,8 @@ protoc_outputs = \ google/protobuf/unittest_custom_options.pb.h \ google/protobuf/unittest_lite_imports_nonlite.pb.cc \ google/protobuf/unittest_lite_imports_nonlite.pb.h \ + google/protobuf/unittest_no_generic_services.pb.cc \ + google/protobuf/unittest_no_generic_services.pb.h \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h @@ -690,9 +702,14 @@ protobuf_test_SOURCES = \ google/protobuf/io/zero_copy_stream_unittest.cc \ google/protobuf/compiler/command_line_interface_unittest.cc \ google/protobuf/compiler/importer_unittest.cc \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/compiler/mock_code_generator.h \ google/protobuf/compiler/parser_unittest.cc \ google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ google/protobuf/compiler/cpp/cpp_unittest.cc \ + google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ + google/protobuf/compiler/java/java_plugin_unittest.cc \ + google/protobuf/compiler/python/python_plugin_unittest.cc \ $(COMMON_TEST_SOURCES) nodist_protobuf_test_SOURCES = $(protoc_outputs) @@ -722,6 +739,20 @@ protobuf_lite_test_SOURCES = \ google/protobuf/test_util_lite.h nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs) + +# Test plugin binary. +test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \ + $(top_builddir)/gtest/lib/libgtest.la + +test_plugin_CPPFLAGS = -I$(top_srcdir)/gtest/include \ + -I$(top_builddir)/gtest/include + +test_plugin_SOURCES = \ + google/protobuf/compiler/mock_code_generator.cc \ + google/protobuf/testing/file.cc \ + google/protobuf/testing/file.h \ + google/protobuf/compiler/test_plugin.cc + @HAVE_ZLIB_TRUE@zcgzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la @HAVE_ZLIB_TRUE@zcgzip_SOURCES = google/protobuf/testing/zcgzip.cc @HAVE_ZLIB_TRUE@zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la @@ -840,6 +871,9 @@ protobuf-test$(EXEEXT): $(protobuf_test_OBJECTS) $(protobuf_test_DEPENDENCIES) protoc$(EXEEXT): $(protoc_OBJECTS) $(protoc_DEPENDENCIES) @rm -f protoc$(EXEEXT) $(CXXLINK) $(protoc_OBJECTS) $(protoc_LDADD) $(LIBS) +test_plugin$(EXEEXT): $(test_plugin_OBJECTS) $(test_plugin_DEPENDENCIES) + @rm -f test_plugin$(EXEEXT) + $(CXXLINK) $(test_plugin_OBJECTS) $(test_plugin_LDADD) $(LIBS) zcgunzip$(EXEEXT): $(zcgunzip_OBJECTS) $(zcgunzip_DEPENDENCIES) @rm -f zcgunzip$(EXEEXT) $(CXXLINK) $(zcgunzip_OBJECTS) $(zcgunzip_LDADD) $(LIBS) @@ -891,20 +925,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_message_field.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_primitive_field.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_service.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_enum.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_enum_field.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_field.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_file.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_generator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_helpers.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_message.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_message_field.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_primitive_field.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message_lite.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/once.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.pb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po@am__quote@ @@ -920,6 +947,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-lite_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-test_util_lite.Po@am__quote@ @@ -929,6 +957,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-common_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-cpp_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po@am__quote@ @@ -939,10 +968,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-googletest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-importer_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-java_plugin_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-message_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-mock_code_generator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-once_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-parser_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-printer_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-python_plugin_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-repeated_field_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po@am__quote@ @@ -959,6 +991,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_lite.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_mset.pb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-wire_format_unittest.Po@am__quote@ @@ -969,7 +1002,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/structurally_valid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strutil.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subprocess.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/substitute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-mock_code_generator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin-test_plugin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text_format.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tokenizer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown_field_set.Plo@am__quote@ @@ -980,6 +1017,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream_impl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero_copy_stream_impl_lite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zip_writer.Plo@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -1240,6 +1278,34 @@ command_line_interface.lo: google/protobuf/compiler/command_line_interface.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o command_line_interface.lo `test -f 'google/protobuf/compiler/command_line_interface.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface.cc +plugin.lo: google/protobuf/compiler/plugin.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT plugin.lo -MD -MP -MF $(DEPDIR)/plugin.Tpo -c -o plugin.lo `test -f 'google/protobuf/compiler/plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/plugin.Tpo $(DEPDIR)/plugin.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/plugin.cc' object='plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o plugin.lo `test -f 'google/protobuf/compiler/plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.cc + +plugin.pb.lo: google/protobuf/compiler/plugin.pb.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT plugin.pb.lo -MD -MP -MF $(DEPDIR)/plugin.pb.Tpo -c -o plugin.pb.lo `test -f 'google/protobuf/compiler/plugin.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.pb.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/plugin.pb.Tpo $(DEPDIR)/plugin.pb.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/plugin.pb.cc' object='plugin.pb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o plugin.pb.lo `test -f 'google/protobuf/compiler/plugin.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/plugin.pb.cc + +subprocess.lo: google/protobuf/compiler/subprocess.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT subprocess.lo -MD -MP -MF $(DEPDIR)/subprocess.Tpo -c -o subprocess.lo `test -f 'google/protobuf/compiler/subprocess.cc' || echo '$(srcdir)/'`google/protobuf/compiler/subprocess.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/subprocess.Tpo $(DEPDIR)/subprocess.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/subprocess.cc' object='subprocess.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o subprocess.lo `test -f 'google/protobuf/compiler/subprocess.cc' || echo '$(srcdir)/'`google/protobuf/compiler/subprocess.cc + +zip_writer.lo: google/protobuf/compiler/zip_writer.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zip_writer.lo -MD -MP -MF $(DEPDIR)/zip_writer.Tpo -c -o zip_writer.lo `test -f 'google/protobuf/compiler/zip_writer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/zip_writer.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zip_writer.Tpo $(DEPDIR)/zip_writer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/zip_writer.cc' object='zip_writer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zip_writer.lo `test -f 'google/protobuf/compiler/zip_writer.cc' || echo '$(srcdir)/'`google/protobuf/compiler/zip_writer.cc + cpp_enum.lo: google/protobuf/compiler/cpp/cpp_enum.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cpp_enum.lo -MD -MP -MF $(DEPDIR)/cpp_enum.Tpo -c -o cpp_enum.lo `test -f 'google/protobuf/compiler/cpp/cpp_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_enum.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/cpp_enum.Tpo $(DEPDIR)/cpp_enum.Plo @@ -1401,69 +1467,6 @@ java_service.lo: google/protobuf/compiler/java/java_service.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_service.lo `test -f 'google/protobuf/compiler/java/java_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_service.cc -javamicro_enum.lo: google/protobuf/compiler/javamicro/javamicro_enum.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_enum.lo -MD -MP -MF $(DEPDIR)/javamicro_enum.Tpo -c -o javamicro_enum.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_enum.Tpo $(DEPDIR)/javamicro_enum.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_enum.cc' object='javamicro_enum.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_enum.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum.cc - -javamicro_enum_field.lo: google/protobuf/compiler/javamicro/javamicro_enum_field.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_enum_field.lo -MD -MP -MF $(DEPDIR)/javamicro_enum_field.Tpo -c -o javamicro_enum_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum_field.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_enum_field.Tpo $(DEPDIR)/javamicro_enum_field.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_enum_field.cc' object='javamicro_enum_field.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_enum_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum_field.cc - -javamicro_field.lo: google/protobuf/compiler/javamicro/javamicro_field.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_field.lo -MD -MP -MF $(DEPDIR)/javamicro_field.Tpo -c -o javamicro_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_field.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_field.Tpo $(DEPDIR)/javamicro_field.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_field.cc' object='javamicro_field.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_field.cc - -javamicro_file.lo: google/protobuf/compiler/javamicro/javamicro_file.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_file.lo -MD -MP -MF $(DEPDIR)/javamicro_file.Tpo -c -o javamicro_file.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_file.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_file.Tpo $(DEPDIR)/javamicro_file.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_file.cc' object='javamicro_file.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_file.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_file.cc - -javamicro_generator.lo: google/protobuf/compiler/javamicro/javamicro_generator.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_generator.lo -MD -MP -MF $(DEPDIR)/javamicro_generator.Tpo -c -o javamicro_generator.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_generator.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_generator.Tpo $(DEPDIR)/javamicro_generator.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_generator.cc' object='javamicro_generator.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_generator.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_generator.cc - -javamicro_helpers.lo: google/protobuf/compiler/javamicro/javamicro_helpers.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_helpers.lo -MD -MP -MF $(DEPDIR)/javamicro_helpers.Tpo -c -o javamicro_helpers.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_helpers.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_helpers.Tpo $(DEPDIR)/javamicro_helpers.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_helpers.cc' object='javamicro_helpers.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_helpers.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_helpers.cc - -javamicro_message.lo: google/protobuf/compiler/javamicro/javamicro_message.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_message.lo -MD -MP -MF $(DEPDIR)/javamicro_message.Tpo -c -o javamicro_message.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_message.Tpo $(DEPDIR)/javamicro_message.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_message.cc' object='javamicro_message.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_message.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message.cc - -javamicro_message_field.lo: google/protobuf/compiler/javamicro/javamicro_message_field.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_message_field.lo -MD -MP -MF $(DEPDIR)/javamicro_message_field.Tpo -c -o javamicro_message_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message_field.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_message_field.Tpo $(DEPDIR)/javamicro_message_field.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_message_field.cc' object='javamicro_message_field.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_message_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message_field.cc - -javamicro_primitive_field.lo: google/protobuf/compiler/javamicro/javamicro_primitive_field.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_primitive_field.lo -MD -MP -MF $(DEPDIR)/javamicro_primitive_field.Tpo -c -o javamicro_primitive_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_primitive_field.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_primitive_field.Tpo $(DEPDIR)/javamicro_primitive_field.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' object='javamicro_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_primitive_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_primitive_field.cc - python_generator.lo: google/protobuf/compiler/python/python_generator.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT python_generator.lo -MD -MP -MF $(DEPDIR)/python_generator.Tpo -c -o python_generator.lo `test -f 'google/protobuf/compiler/python/python_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_generator.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/python_generator.Tpo $(DEPDIR)/python_generator.Plo @@ -1667,6 +1670,20 @@ protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj: google/proto @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi` +protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc + +protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` + protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po @@ -2031,6 +2048,20 @@ protobuf_test-importer_unittest.obj: google/protobuf/compiler/importer_unittest. @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi` +protobuf_test-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-mock_code_generator.o -MD -MP -MF $(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-mock_code_generator.Tpo $(DEPDIR)/protobuf_test-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='protobuf_test-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc + +protobuf_test-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-mock_code_generator.obj -MD -MP -MF $(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-mock_code_generator.Tpo $(DEPDIR)/protobuf_test-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='protobuf_test-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` + protobuf_test-parser_unittest.o: google/protobuf/compiler/parser_unittest.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-parser_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-parser_unittest.Tpo $(DEPDIR)/protobuf_test-parser_unittest.Po @@ -2073,6 +2104,48 @@ protobuf_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` +protobuf_test-cpp_plugin_unittest.o: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='protobuf_test-cpp_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc + +protobuf_test-cpp_plugin_unittest.obj: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='protobuf_test-cpp_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi` + +protobuf_test-java_plugin_unittest.o: google/protobuf/compiler/java/java_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-java_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='protobuf_test-java_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc + +protobuf_test-java_plugin_unittest.obj: google/protobuf/compiler/java/java_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-java_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='protobuf_test-java_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi` + +protobuf_test-python_plugin_unittest.o: google/protobuf/compiler/python/python_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-python_plugin_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-python_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='protobuf_test-python_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc + +protobuf_test-python_plugin_unittest.obj: google/protobuf/compiler/python/python_plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-python_plugin_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-python_plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='protobuf_test-python_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi` + protobuf_test-test_util.o: google/protobuf/test_util.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-test_util.o -MD -MP -MF $(DEPDIR)/protobuf_test-test_util.Tpo -c -o protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-test_util.Tpo $(DEPDIR)/protobuf_test-test_util.Po @@ -2255,6 +2328,20 @@ protobuf_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lit @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi` +protobuf_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_no_generic_services.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc + +protobuf_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_no_generic_services.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo $(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_no_generic_services.pb.cc' object='protobuf_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi` + protobuf_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo $(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po @@ -2283,6 +2370,48 @@ main.obj: google/protobuf/compiler/main.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o main.obj `if test -f 'google/protobuf/compiler/main.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/main.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/main.cc'; fi` +test_plugin-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-mock_code_generator.o -MD -MP -MF $(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/test_plugin-mock_code_generator.Tpo $(DEPDIR)/test_plugin-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='test_plugin-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc + +test_plugin-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-mock_code_generator.obj -MD -MP -MF $(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/test_plugin-mock_code_generator.Tpo $(DEPDIR)/test_plugin-mock_code_generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/mock_code_generator.cc' object='test_plugin-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi` + +test_plugin-file.o: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-file.o -MD -MP -MF $(DEPDIR)/test_plugin-file.Tpo -c -o test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/test_plugin-file.Tpo $(DEPDIR)/test_plugin-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='test_plugin-file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc + +test_plugin-file.obj: google/protobuf/testing/file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-file.obj -MD -MP -MF $(DEPDIR)/test_plugin-file.Tpo -c -o test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/test_plugin-file.Tpo $(DEPDIR)/test_plugin-file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/testing/file.cc' object='test_plugin-file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi` + +test_plugin-test_plugin.o: google/protobuf/compiler/test_plugin.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-test_plugin.o -MD -MP -MF $(DEPDIR)/test_plugin-test_plugin.Tpo -c -o test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/test_plugin-test_plugin.Tpo $(DEPDIR)/test_plugin-test_plugin.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/test_plugin.cc' object='test_plugin-test_plugin.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc + +test_plugin-test_plugin.obj: google/protobuf/compiler/test_plugin.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_plugin-test_plugin.obj -MD -MP -MF $(DEPDIR)/test_plugin-test_plugin.Tpo -c -o test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/test_plugin-test_plugin.Tpo $(DEPDIR)/test_plugin-test_plugin.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/test_plugin.cc' object='test_plugin-test_plugin.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi` + zcgunzip.o: google/protobuf/testing/zcgunzip.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zcgunzip.o -MD -MP -MF $(DEPDIR)/zcgunzip.Tpo -c -o zcgunzip.o `test -f 'google/protobuf/testing/zcgunzip.cc' || echo '$(srcdir)/'`google/protobuf/testing/zcgunzip.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zcgunzip.Tpo $(DEPDIR)/zcgunzip.Po @@ -2630,21 +2759,14 @@ clean-local: rm -f *.loT @USE_EXTERNAL_PROTOC_TRUE@unittest_proto_middleman: $(protoc_inputs) -@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) --cpp_out=. $(protoc_inputs) +@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) --cpp_out=. $^ @USE_EXTERNAL_PROTOC_TRUE@ touch unittest_proto_middleman -# This rule is a little weird. The first prereq is the protoc executable -# and the rest are its inputs. Therefore, $^ -- which expands to the -# list of prereqs -- is actually a valid command. We have to place "./" in -# front of it in case protoc is in the current directory. protoc allows -# flags to appear after input file names, so we happily stick the flags on -# the end. -# -# For reference, if we didn't have to worry about VPATH (i.e., building from -# a directory other than the package root), we could have just written this: -# ./protoc$(EXEEXT) -I$(srcdir) --cpp_out=. $(protoc_inputs) +# 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. @USE_EXTERNAL_PROTOC_FALSE@unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs) -@USE_EXTERNAL_PROTOC_FALSE@ ./$^ -I$(srcdir) --cpp_out=. +@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) ) @USE_EXTERNAL_PROTOC_FALSE@ touch unittest_proto_middleman $(protoc_outputs): unittest_proto_middleman diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index 0def84d..3413a36 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -34,6 +34,7 @@ #include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/strutil.h> namespace google { @@ -43,9 +44,15 @@ namespace compiler { CodeGenerator::~CodeGenerator() {} OutputDirectory::~OutputDirectory() {} +io::ZeroCopyOutputStream* OutputDirectory::OpenForInsert( + const string& filename, const string& insertion_point) { + GOOGLE_LOG(FATAL) << "This OutputDirectory does not support insertion."; + return NULL; // make compiler happy +} + // Parses a set of comma-delimited name/value pairs. void ParseGeneratorParameter(const string& text, - vector<pair<string, string> >* output) { + vector<pair<string, string> >* output) { vector<string> parts; SplitStringUsing(text, ",", &parts); diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 8a7081f..ea094cd 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -98,11 +98,20 @@ class LIBPROTOC_EXPORT OutputDirectory { // // The filename given should be relative to the root of the source tree. // E.g. the C++ generator, when generating code for "foo/bar.proto", will - // generate the files "foo/bar.pb2.h" and "foo/bar.pb2.cc"; note that + // generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that // "foo/" is included in these filenames. The filename is not allowed to // contain "." or ".." components. virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0; + // Creates a ZeroCopyOutputStream which will insert code into the given file + // at the given insertion point. See plugin.proto (plugin.pb.h) for more + // information on insertion points. The default implementation + // assert-fails -- it exists only for backwards-compatibility. + // + // WARNING: This feature is currently EXPERIMENTAL and is subject to change. + virtual io::ZeroCopyOutputStream* OpenForInsert( + const string& filename, const string& insertion_point); + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OutputDirectory); }; @@ -114,7 +123,7 @@ class LIBPROTOC_EXPORT OutputDirectory { // parses to the pairs: // ("foo", "bar"), ("baz", ""), ("qux", "corge") extern void ParseGeneratorParameter(const string&, - vector<pair<string, string> >*); + vector<pair<string, string> >*); } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 3629f68..d3495ca 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -32,6 +32,8 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/compiler/command_line_interface.h> + #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -46,15 +48,22 @@ #include <iostream> #include <ctype.h> -#include <google/protobuf/compiler/command_line_interface.h> #include <google/protobuf/compiler/importer.h> #include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.pb.h> +#include <google/protobuf/compiler/subprocess.h> +#include <google/protobuf/compiler/zip_writer.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/text_format.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/map-util.h> +#include <google/protobuf/stubs/stl_util-inl.h> +#include <google/protobuf/stubs/hash.h> namespace google { @@ -126,6 +135,47 @@ void SetFdToBinaryMode(int fd) { // (Text and binary are the same on non-Windows platforms.) } +void AddTrailingSlash(string* path) { + if (!path->empty() && path->at(path->size() - 1) != '/') { + path->push_back('/'); + } +} + +bool VerifyDirectoryExists(const string& path) { + if (path.empty()) return true; + + if (access(path.c_str(), W_OK) == -1) { + cerr << path << ": " << strerror(errno) << endl; + return false; + } else { + return true; + } +} + +// Try to create the parent directory of the given file, creating the parent's +// parent if necessary, and so on. The full file name is actually +// (prefix + filename), but we assume |prefix| already exists and only create +// directories listed in |filename|. +bool TryCreateParentDirectory(const string& prefix, const string& filename) { + // Recursively create parent directories to the output file. + vector<string> parts; + SplitStringUsing(filename, "/", &parts); + string path_so_far = prefix; + for (int i = 0; i < parts.size() - 1; i++) { + path_so_far += parts[i]; + if (mkdir(path_so_far.c_str(), 0777) != 0) { + if (errno != EEXIST) { + cerr << filename << ": while trying to create directory " + << path_so_far << ": " << strerror(errno) << endl; + return false; + } + } + path_so_far += '/'; + } + + return true; +} + } // namespace // A MultiFileErrorCollector that prints errors to stderr. @@ -169,72 +219,142 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, // ------------------------------------------------------------------- -// An OutputDirectory implementation that writes to disk. -class CommandLineInterface::DiskOutputDirectory : public OutputDirectory { +// An OutputDirectory implementation that buffers files in memory, then dumps +// them all to disk on demand. +class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory { public: - DiskOutputDirectory(const string& root); - ~DiskOutputDirectory(); + MemoryOutputDirectory(); + ~MemoryOutputDirectory(); + + // Write all files in the directory to disk at the given output location, + // which must end in a '/'. + bool WriteAllToDisk(const string& prefix); - bool VerifyExistence(); + // Write the contents of this directory to a ZIP-format archive with the + // given name. + bool WriteAllToZip(const string& filename); - inline bool had_error() { return had_error_; } - inline void set_had_error(bool value) { had_error_ = value; } + // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR + // format, unless one has already been written. + void AddJarManifest(); // implements OutputDirectory -------------------------------------- io::ZeroCopyOutputStream* Open(const string& filename); + io::ZeroCopyOutputStream* OpenForInsert( + const string& filename, const string& insertion_point); private: - string root_; + friend class MemoryOutputStream; + + // map instead of hash_map so that files are written in order (good when + // writing zips). + map<string, string*> files_; bool had_error_; }; -// A FileOutputStream that checks for errors in the destructor and reports -// them. We extend FileOutputStream via wrapping rather than inheritance -// for two reasons: -// 1) Implementation inheritance is evil. -// 2) We need to close the file descriptor *after* the FileOutputStream's -// destructor is run to make sure it flushes the file contents. -class CommandLineInterface::ErrorReportingFileOutput +class CommandLineInterface::MemoryOutputStream : public io::ZeroCopyOutputStream { public: - ErrorReportingFileOutput(int file_descriptor, - const string& filename, - DiskOutputDirectory* directory); - ~ErrorReportingFileOutput(); + MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename); + MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename, + const string& insertion_point); + virtual ~MemoryOutputStream(); // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size) { return file_stream_->Next(data, size); } - void BackUp(int count) { file_stream_->BackUp(count); } - int64 ByteCount() const { return file_stream_->ByteCount(); } + virtual bool Next(void** data, int* size) { return inner_->Next(data, size); } + virtual void BackUp(int count) { inner_->BackUp(count); } + virtual int64 ByteCount() const { return inner_->ByteCount(); } private: - scoped_ptr<io::FileOutputStream> file_stream_; - int file_descriptor_; + // Where to insert the string when it's done. + MemoryOutputDirectory* directory_; string filename_; - DiskOutputDirectory* directory_; + string insertion_point_; + + // The string we're building. + string data_; + + // StringOutputStream writing to data_. + scoped_ptr<io::StringOutputStream> inner_; }; // ------------------------------------------------------------------- -CommandLineInterface::DiskOutputDirectory::DiskOutputDirectory( - const string& root) - : root_(root), had_error_(false) { - // Add a '/' to the end if it doesn't already have one. But don't add a - // '/' to an empty string since this probably means the current directory. - if (!root_.empty() && root[root_.size() - 1] != '/') { - root_ += '/'; - } -} +CommandLineInterface::MemoryOutputDirectory::MemoryOutputDirectory() + : had_error_(false) {} -CommandLineInterface::DiskOutputDirectory::~DiskOutputDirectory() { +CommandLineInterface::MemoryOutputDirectory::~MemoryOutputDirectory() { + STLDeleteValues(&files_); } -bool CommandLineInterface::DiskOutputDirectory::VerifyExistence() { - if (!root_.empty()) { - // Make sure the directory exists. If it isn't a directory, this will fail - // because we added a '/' to the end of the name in the constructor. - if (access(root_.c_str(), W_OK) == -1) { - cerr << root_ << ": " << strerror(errno) << endl; +bool CommandLineInterface::MemoryOutputDirectory::WriteAllToDisk( + const string& prefix) { + if (had_error_) { + return false; + } + + if (!VerifyDirectoryExists(prefix)) { + return false; + } + + for (map<string, string*>::const_iterator iter = files_.begin(); + iter != files_.end(); ++iter) { + const string& relative_filename = iter->first; + const char* data = iter->second->data(); + int size = iter->second->size(); + + if (!TryCreateParentDirectory(prefix, relative_filename)) { + return false; + } + string filename = prefix + relative_filename; + + // Create the output file. + int file_descriptor; + do { + file_descriptor = + open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); + } while (file_descriptor < 0 && errno == EINTR); + + if (file_descriptor < 0) { + int error = errno; + cerr << filename << ": " << strerror(error); + return false; + } + + // Write the file. + while (size > 0) { + int write_result; + do { + write_result = write(file_descriptor, data, size); + } while (write_result < 0 && errno == EINTR); + + if (write_result <= 0) { + // Write error. + + // FIXME(kenton): According to the man page, if write() returns zero, + // there was no error; write() simply did not write anything. It's + // unclear under what circumstances this might happen, but presumably + // errno won't be set in this case. I am confused as to how such an + // event should be handled. For now I'm treating it as an error, + // since retrying seems like it could lead to an infinite loop. I + // suspect this never actually happens anyway. + + if (write_result < 0) { + int error = errno; + cerr << filename << ": write: " << strerror(error); + } else { + cerr << filename << ": write() returned zero?" << endl; + } + return false; + } + + data += write_result; + size -= write_result; + } + + if (close(file_descriptor) != 0) { + int error = errno; + cerr << filename << ": close: " << strerror(error); return false; } } @@ -242,65 +362,183 @@ bool CommandLineInterface::DiskOutputDirectory::VerifyExistence() { return true; } -io::ZeroCopyOutputStream* CommandLineInterface::DiskOutputDirectory::Open( +bool CommandLineInterface::MemoryOutputDirectory::WriteAllToZip( const string& filename) { - // Recursively create parent directories to the output file. - vector<string> parts; - SplitStringUsing(filename, "/", &parts); - string path_so_far = root_; - for (int i = 0; i < parts.size() - 1; i++) { - path_so_far += parts[i]; - if (mkdir(path_so_far.c_str(), 0777) != 0) { - if (errno != EEXIST) { - cerr << filename << ": while trying to create directory " - << path_so_far << ": " << strerror(errno) << endl; - had_error_ = true; - // Return a dummy stream. - return new io::ArrayOutputStream(NULL, 0); - } - } - path_so_far += '/'; + if (had_error_) { + return false; } // Create the output file. int file_descriptor; do { file_descriptor = - open((root_ + filename).c_str(), - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); + open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); } while (file_descriptor < 0 && errno == EINTR); if (file_descriptor < 0) { - // Failed to open. - cerr << filename << ": " << strerror(errno) << endl; - had_error_ = true; - // Return a dummy stream. - return new io::ArrayOutputStream(NULL, 0); + int error = errno; + cerr << filename << ": " << strerror(error); + return false; } - return new ErrorReportingFileOutput(file_descriptor, filename, this); -} + // Create the ZipWriter + io::FileOutputStream stream(file_descriptor); + ZipWriter zip_writer(&stream); + + for (map<string, string*>::const_iterator iter = files_.begin(); + iter != files_.end(); ++iter) { + zip_writer.Write(iter->first, *iter->second); + } + + zip_writer.WriteDirectory(); + + if (stream.GetErrno() != 0) { + cerr << filename << ": " << strerror(stream.GetErrno()) << endl; + } -CommandLineInterface::ErrorReportingFileOutput::ErrorReportingFileOutput( - int file_descriptor, - const string& filename, - DiskOutputDirectory* directory) - : file_stream_(new io::FileOutputStream(file_descriptor)), - file_descriptor_(file_descriptor), - filename_(filename), - directory_(directory) {} + if (!stream.Close()) { + cerr << filename << ": " << strerror(stream.GetErrno()) << endl; + } + + return true; +} -CommandLineInterface::ErrorReportingFileOutput::~ErrorReportingFileOutput() { - // Check if we had any errors while writing. - if (file_stream_->GetErrno() != 0) { - cerr << filename_ << ": " << strerror(file_stream_->GetErrno()) << endl; - directory_->set_had_error(true); +void CommandLineInterface::MemoryOutputDirectory::AddJarManifest() { + string** map_slot = &files_["META-INF/MANIFEST.MF"]; + if (*map_slot == NULL) { + *map_slot = new string( + "Manifest-Version: 1.0\n" + "Created-By: 1.6.0 (protoc)\n" + "\n"); } +} + +io::ZeroCopyOutputStream* CommandLineInterface::MemoryOutputDirectory::Open( + const string& filename) { + return new MemoryOutputStream(this, filename); +} + +io::ZeroCopyOutputStream* +CommandLineInterface::MemoryOutputDirectory::OpenForInsert( + const string& filename, const string& insertion_point) { + return new MemoryOutputStream(this, filename, insertion_point); +} + +// ------------------------------------------------------------------- + +CommandLineInterface::MemoryOutputStream::MemoryOutputStream( + MemoryOutputDirectory* directory, const string& filename) + : directory_(directory), + filename_(filename), + inner_(new io::StringOutputStream(&data_)) { +} + +CommandLineInterface::MemoryOutputStream::MemoryOutputStream( + MemoryOutputDirectory* directory, const string& filename, + const string& insertion_point) + : directory_(directory), + filename_(filename), + insertion_point_(insertion_point), + inner_(new io::StringOutputStream(&data_)) { +} + +CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { + // Make sure all data has been written. + inner_.reset(); - // Close the file stream. - if (!file_stream_->Close()) { - cerr << filename_ << ": " << strerror(file_stream_->GetErrno()) << endl; - directory_->set_had_error(true); + // Insert into the directory. + string** map_slot = &directory_->files_[filename_]; + + if (insertion_point_.empty()) { + // This was just a regular Open(). + if (*map_slot != NULL) { + cerr << filename_ << ": Tried to write the same file twice." << endl; + directory_->had_error_ = true; + return; + } + + *map_slot = new string; + (*map_slot)->swap(data_); + } else { + // This was an OpenForInsert(). + + // If the data doens't end with a clean line break, add one. + if (!data_.empty() && data_[data_.size() - 1] != '\n') { + data_.push_back('\n'); + } + + // Find the file we are going to insert into. + if (*map_slot == NULL) { + cerr << filename_ << ": Tried to insert into file that doesn't exist." + << endl; + directory_->had_error_ = true; + return; + } + string* target = *map_slot; + + // Find the insertion point. + string magic_string = strings::Substitute( + "@@protoc_insertion_point($0)", insertion_point_); + string::size_type pos = target->find(magic_string); + + if (pos == string::npos) { + cerr << filename_ << ": insertion point \"" << insertion_point_ + << "\" not found." << endl; + directory_->had_error_ = true; + return; + } + + // Seek backwards to the beginning of the line, which is where we will + // insert the data. Note that this has the effect of pushing the insertion + // point down, so the data is inserted before it. This is intentional + // because it means that multiple insertions at the same point will end + // up in the expected order in the final output. + pos = target->find_last_of('\n', pos); + if (pos == string::npos) { + // Insertion point is on the first line. + pos = 0; + } else { + // Advance to character after '\n'. + ++pos; + } + + // Extract indent. + string indent_(*target, pos, target->find_first_not_of(" \t", pos) - pos); + + if (indent_.empty()) { + // No indent. This makes things easier. + target->insert(pos, data_); + } else { + // Calculate how much space we need. + int indent_size = 0; + for (int i = 0; i < data_.size(); i++) { + if (data_[i] == '\n') indent_size += indent_.size(); + } + + // Make a hole for it. + target->insert(pos, data_.size() + indent_size, '\0'); + + // Now copy in the data. + string::size_type data_pos = 0; + char* target_ptr = string_as_array(target) + pos; + while (data_pos < data_.size()) { + // Copy indent. + memcpy(target_ptr, indent_.data(), indent_.size()); + target_ptr += indent_.size(); + + // Copy line from data_. + // We already guaranteed that data_ ends with a newline (above), so this + // search can't fail. + string::size_type line_length = + data_.find_first_of('\n', data_pos) + 1 - data_pos; + memcpy(target_ptr, data_.data() + data_pos, line_length); + target_ptr += line_length; + data_pos += line_length; + } + + GOOGLE_CHECK_EQ(target_ptr, + string_as_array(target) + pos + data_.size() + indent_size); + } } } @@ -323,6 +561,10 @@ void CommandLineInterface::RegisterGenerator(const string& flag_name, generators_[flag_name] = info; } +void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) { + plugin_prefix_ = exe_name_prefix; +} + int CommandLineInterface::Run(int argc, const char* const argv[]) { Clear(); if (!ParseArguments(argc, argv)) return 1; @@ -346,7 +588,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { vector<const FileDescriptor*> parsed_files; - // Parse each file and generate output. + // Parse each file. for (int i = 0; i < input_files_.size(); i++) { // Import the file. const FileDescriptor* parsed_file = importer.Import(input_files_[i]); @@ -359,17 +601,60 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { "--disallow_services was used." << endl; return 1; } + } + + // We construct a separate OutputDirectory for each output location. Note + // that two code generators may output to the same location, in which case + // they should share a single OutputDirectory (so that OpenForInsert() works). + typedef hash_map<string, MemoryOutputDirectory*> OutputDirectoryMap; + OutputDirectoryMap output_directories; + + // Generate output. + if (mode_ == MODE_COMPILE) { + for (int i = 0; i < output_directives_.size(); i++) { + string output_location = output_directives_[i].output_location; + if (!HasSuffixString(output_location, ".zip") && + !HasSuffixString(output_location, ".jar")) { + AddTrailingSlash(&output_location); + } + MemoryOutputDirectory** map_slot = &output_directories[output_location]; + + if (*map_slot == NULL) { + // First time we've seen this output location. + *map_slot = new MemoryOutputDirectory; + } + + if (!GenerateOutput(parsed_files, output_directives_[i], *map_slot)) { + STLDeleteValues(&output_directories); + return 1; + } + } + } - if (mode_ == MODE_COMPILE) { - // Generate output files. - for (int i = 0; i < output_directives_.size(); i++) { - if (!GenerateOutput(parsed_file, output_directives_[i])) { - return 1; - } + // Write all output to disk. + for (OutputDirectoryMap::iterator iter = output_directories.begin(); + iter != output_directories.end(); ++iter) { + const string& location = iter->first; + MemoryOutputDirectory* directory = iter->second; + if (HasSuffixString(location, "/")) { + if (!directory->WriteAllToDisk(location)) { + STLDeleteValues(&output_directories); + return 1; + } + } else { + if (HasSuffixString(location, ".jar")) { + directory->AddJarManifest(); + } + + if (!directory->WriteAllToZip(location)) { + STLDeleteValues(&output_directories); + return 1; } } } + STLDeleteValues(&output_directories); + if (!descriptor_set_name_.empty()) { if (!WriteDescriptorSet(parsed_files)) { return 1; @@ -439,7 +724,11 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative( } else { cerr << input_files_[i] << ": File does not reside within any path " "specified using --proto_path (or -I). You must specify a " - "--proto_path which encompasses this file." << endl; + "--proto_path which encompasses this file. Note that the " + "proto_path must be an exact prefix of the .proto file " + "names -- protoc is too dumb to figure out when two paths " + "(e.g. absolute and relative) are equivalent (it's harder " + "than you think)." << endl; } return false; } @@ -682,10 +971,37 @@ bool CommandLineInterface::InterpretArgument(const string& name, return false; } + } else if (name == "--plugin") { + if (plugin_prefix_.empty()) { + cerr << "This compiler does not support plugins." << endl; + return false; + } + + string name; + string path; + + string::size_type equals_pos = value.find_first_of('='); + if (equals_pos == string::npos) { + // Use the basename of the file. + string::size_type slash_pos = value.find_last_of('/'); + if (slash_pos == string::npos) { + name = value; + } else { + name = value.substr(slash_pos + 1); + } + path = value; + } else { + name = value.substr(0, equals_pos); + path = value.substr(equals_pos + 1); + } + + plugins_[name] = path; + } else { // Some other flag. Look it up in the generators list. - GeneratorMap::const_iterator iter = generators_.find(name); - if (iter == generators_.end()) { + const GeneratorInfo* generator_info = FindOrNull(generators_, name); + if (generator_info == NULL && + (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { cerr << "Unknown flag: " << name << endl; return false; } @@ -699,7 +1015,11 @@ bool CommandLineInterface::InterpretArgument(const string& name, OutputDirective directive; directive.name = name; - directive.generator = iter->second.generator; + if (generator_info == NULL) { + directive.generator = NULL; + } else { + directive.generator = generator_info->generator; + } // Split value at ':' to separate the generator parameter from the // filename. However, avoid doing this if the colon is part of a valid @@ -751,6 +1071,17 @@ void CommandLineInterface::PrintHelpText() { " --error_format=FORMAT Set the format in which to print errors.\n" " FORMAT may be 'gcc' (the default) or 'msvs'\n" " (Microsoft Visual Studio format)." << endl; + if (!plugin_prefix_.empty()) { + cerr << +" --plugin=EXECUTABLE Specifies a plugin executable to use.\n" +" Normally, protoc searches the PATH for\n" +" plugins, but you may specify additional\n" +" executables not in the path using this flag.\n" +" Additionally, EXECUTABLE may be of the form\n" +" NAME=PATH, in which case the given plugin name\n" +" is mapped to the given executable even if\n" +" the executable's own name differs." << endl; + } for (GeneratorMap::iterator iter = generators_.begin(); iter != generators_.end(); ++iter) { @@ -764,28 +1095,116 @@ void CommandLineInterface::PrintHelpText() { } bool CommandLineInterface::GenerateOutput( - const FileDescriptor* parsed_file, - const OutputDirective& output_directive) { - // Create the output directory. - DiskOutputDirectory output_directory(output_directive.output_location); - if (!output_directory.VerifyExistence()) { - return false; + const vector<const FileDescriptor*>& parsed_files, + const OutputDirective& output_directive, + OutputDirectory* output_directory) { + // Call the generator. + string error; + if (output_directive.generator == NULL) { + // This is a plugin. + GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") && + HasSuffixString(output_directive.name, "_out")) + << "Bad name for plugin generator: " << output_directive.name; + + // Strip the "--" and "_out" and add the plugin prefix. + string plugin_name = plugin_prefix_ + "gen-" + + output_directive.name.substr(2, output_directive.name.size() - 6); + + if (!GeneratePluginOutput(parsed_files, plugin_name, + output_directive.parameter, + output_directory, &error)) { + cerr << output_directive.name << ": " << error << endl; + return false; + } + } else { + // Regular generator. + for (int i = 0; i < parsed_files.size(); i++) { + if (!output_directive.generator->Generate( + parsed_files[i], output_directive.parameter, + output_directory, &error)) { + // Generator returned an error. + cerr << output_directive.name << ": " << parsed_files[i]->name() << ": " + << error << endl; + return false; + } + } } - // Opened successfully. Write it. + return true; +} - // Call the generator. - string error; - if (!output_directive.generator->Generate( - parsed_file, output_directive.parameter, &output_directory, &error)) { - // Generator returned an error. - cerr << parsed_file->name() << ": " << output_directive.name << ": " - << error << endl; +bool CommandLineInterface::GeneratePluginOutput( + const vector<const FileDescriptor*>& parsed_files, + const string& plugin_name, + const string& parameter, + OutputDirectory* output_directory, + string* error) { + CodeGeneratorRequest request; + CodeGeneratorResponse response; + + // Build the request. + if (!parameter.empty()) { + request.set_parameter(parameter); + } + + set<const FileDescriptor*> already_seen; + for (int i = 0; i < parsed_files.size(); i++) { + request.add_file_to_generate(parsed_files[i]->name()); + GetTransitiveDependencies(parsed_files[i], &already_seen, + request.mutable_proto_file()); + } + + // Invoke the plugin. + Subprocess subprocess; + + if (plugins_.count(plugin_name) > 0) { + subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME); + } else { + subprocess.Start(plugin_name, Subprocess::SEARCH_PATH); + } + + string communicate_error; + if (!subprocess.Communicate(request, &response, &communicate_error)) { + *error = strings::Substitute("$0: $1", plugin_name, communicate_error); return false; } - // Check for write errors. - if (output_directory.had_error()) { + // Write the files. We do this even if there was a generator error in order + // to match the behavior of a compiled-in generator. + scoped_ptr<io::ZeroCopyOutputStream> current_output; + for (int i = 0; i < response.file_size(); i++) { + const CodeGeneratorResponse::File& output_file = response.file(i); + + if (!output_file.insertion_point().empty()) { + // Open a file for insert. + // We reset current_output to NULL first so that the old file is closed + // before the new one is opened. + current_output.reset(); + current_output.reset(output_directory->OpenForInsert( + output_file.name(), output_file.insertion_point())); + } else if (!output_file.name().empty()) { + // Starting a new file. Open it. + // We reset current_output to NULL first so that the old file is closed + // before the new one is opened. + current_output.reset(); + current_output.reset(output_directory->Open(output_file.name())); + } else if (current_output == NULL) { + *error = strings::Substitute( + "$0: First file chunk returned by plugin did not specify a file name.", + plugin_name); + return false; + } + + // Use CodedOutputStream for convenience; otherwise we'd need to provide + // our own buffer-copying loop. + io::CodedOutputStream writer(current_output.get()); + writer.WriteString(output_file.content()); + } + + // Check for errors. + if (!response.error().empty()) { + // Generator returned an error. + *error = response.error(); return false; } @@ -858,22 +1277,16 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { bool CommandLineInterface::WriteDescriptorSet( const vector<const FileDescriptor*> parsed_files) { FileDescriptorSet file_set; - set<const FileDescriptor*> already_added; - vector<const FileDescriptor*> to_add(parsed_files); - - while (!to_add.empty()) { - const FileDescriptor* file = to_add.back(); - to_add.pop_back(); - if (already_added.insert(file).second) { - // This file was not already in the set. - file->CopyTo(file_set.add_file()); - - if (imports_in_descriptor_set_) { - // Add all of this file's dependencies. - for (int i = 0; i < file->dependency_count(); i++) { - to_add.push_back(file->dependency(i)); - } - } + + if (imports_in_descriptor_set_) { + set<const FileDescriptor*> already_seen; + for (int i = 0; i < parsed_files.size(); i++) { + GetTransitiveDependencies( + parsed_files[i], &already_seen, file_set.mutable_file()); + } + } else { + for (int i = 0; i < parsed_files.size(); i++) { + parsed_files[i]->CopyTo(file_set.add_file()); } } @@ -902,6 +1315,24 @@ bool CommandLineInterface::WriteDescriptorSet( return true; } +void CommandLineInterface::GetTransitiveDependencies( + const FileDescriptor* file, + set<const FileDescriptor*>* already_seen, + RepeatedPtrField<FileDescriptorProto>* output) { + if (!already_seen->insert(file).second) { + // Already saw this file. Skip. + return; + } + + // Add all dependencies. + for (int i = 0; i < file->dependency_count(); i++) { + GetTransitiveDependencies(file->dependency(i), already_seen, output); + } + + // Add this file. + file->CopyTo(output->Add()); +} + } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index ec65863..d25a50e 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -50,10 +50,13 @@ namespace protobuf { class FileDescriptor; // descriptor.h class DescriptorPool; // descriptor.h +class FileDescriptorProto; // descriptor.pb.h +template<typename T> class RepeatedPtrField; // repeated_field.h namespace compiler { class CodeGenerator; // code_generator.h +class OutputDirectory; // code_generator.h class DiskSourceTree; // importer.h // This class implements the command-line interface to the protocol compiler. @@ -109,6 +112,37 @@ class LIBPROTOC_EXPORT CommandLineInterface { CodeGenerator* generator, const string& help_text); + // Enables "plugins". In this mode, if a command-line flag ends with "_out" + // but does not match any registered generator, the compiler will attempt to + // find a "plugin" to implement the generator. Plugins are just executables. + // They should live somewhere in the PATH. + // + // The compiler determines the executable name to search for by concatenating + // exe_name_prefix with the unrecognized flag name, removing "_out". So, for + // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out, + // the compiler will try to run the program "protoc-foo". + // + // The plugin program should implement the following usage: + // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS + // --out indicates the output directory (as passed to the --foo_out + // parameter); if omitted, the current directory should be used. --parameter + // gives the generator parameter, if any was provided. The PROTO_FILES list + // the .proto files which were given on the compiler command-line; these are + // the files for which the plugin is expected to generate output code. + // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in + // descriptor.proto). This is piped to the plugin's stdin. The set will + // include descriptors for all the files listed in PROTO_FILES as well as + // all files that they import. The plugin MUST NOT attempt to read the + // PROTO_FILES directly -- it must use the FileDescriptorSet. + // + // The plugin should generate whatever files are necessary, as code generators + // normally do. It should write the names of all files it generates to + // stdout. The names should be relative to the output directory, NOT absolute + // names or relative to the current directory. If any errors occur, error + // messages should be written to stderr. If an error is fatal, the plugin + // should exit with a non-zero exit code. + void AllowPlugins(const string& exe_name_prefix); + // Run the Protocol Compiler with the given command-line parameters. // Returns the error code which should be returned by main(). // @@ -140,8 +174,8 @@ class LIBPROTOC_EXPORT CommandLineInterface { // ----------------------------------------------------------------- class ErrorPrinter; - class DiskOutputDirectory; - class ErrorReportingFileOutput; + class MemoryOutputDirectory; + class MemoryOutputStream; // Clear state from previous Run(). void Clear(); @@ -176,8 +210,14 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Generate the given output file from the given input. struct OutputDirective; // see below - bool GenerateOutput(const FileDescriptor* proto_file, - const OutputDirective& output_directive); + bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files, + const OutputDirective& output_directive, + OutputDirectory* output_directory); + bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files, + const string& plugin_name, + const string& parameter, + OutputDirectory* output_directory, + string* error); // Implements --encode and --decode. bool EncodeOrDecode(const DescriptorPool* pool); @@ -185,6 +225,17 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Implements the --descriptor_set_out option. bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files); + // Get all transitive dependencies of the given file (including the file + // itself), adding them to the given list of FileDescriptorProtos. The + // protos will be ordered such that every file is listed before any file that + // depends on it, so that you can call DescriptorPool::BuildFile() on them + // in order. Any files in *already_seen will not be added, and each file + // added will be inserted into *already_seen. + static void GetTransitiveDependencies( + const FileDescriptor* file, + set<const FileDescriptor*>* already_seen, + RepeatedPtrField<FileDescriptorProto>* output); + // ----------------------------------------------------------------- // The name of the executable as invoked (i.e. argv[0]). @@ -201,6 +252,14 @@ class LIBPROTOC_EXPORT CommandLineInterface { typedef map<string, GeneratorInfo> GeneratorMap; GeneratorMap generators_; + // See AllowPlugins(). If this is empty, plugins aren't allowed. + string plugin_prefix_; + + // Maps specific plugin names to files. When executing a plugin, this map + // is searched first to find the plugin executable. If not found here, the + // PATH (or other OS-specific search strategy) is searched. + map<string, string> plugins_; + // Stuff parsed from command line. enum Mode { MODE_COMPILE, // Normal mode: parse .proto files and compile them. @@ -223,8 +282,8 @@ class LIBPROTOC_EXPORT CommandLineInterface { // output_directives_ lists all the files we are supposed to output and what // generator to use for each. struct OutputDirective { - string name; - CodeGenerator* generator; + string name; // E.g. "--foo_out" + CodeGenerator* generator; // NULL for plugins string parameter; string output_location; }; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 719771e..9129ebf 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -47,10 +47,12 @@ #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/compiler/command_line_interface.h> #include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/mock_code_generator.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/unittest.pb.h> #include <google/protobuf/testing/file.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/testing/googletest.h> #include <gtest/gtest.h> @@ -66,6 +68,9 @@ namespace compiler { #ifndef STDOUT_FILENO #define STDOUT_FILENO 1 #endif +#ifndef F_OK +#define F_OK 00 // not defined by MSVC for whatever reason +#endif #endif namespace { @@ -83,28 +88,19 @@ class CommandLineInterfaceTest : public testing::Test { // ----------------------------------------------------------------- // Methods to set up the test (called before Run()). - class MockCodeGenerator; class NullCodeGenerator; - // Registers a MockCodeGenerator with the given name. - MockCodeGenerator* RegisterGenerator(const string& generator_name, - const string& flag_name, - const string& filename, - const string& help_text); - MockCodeGenerator* RegisterErrorGenerator(const string& generator_name, - const string& error_text, - const string& flag_name, - const string& filename, - const string& help_text); - - // Registers a CodeGenerator which will not actually generate anything, - // but records the parameter passed to the generator. - NullCodeGenerator* RegisterNullGenerator(const string& flag_name); + // Normally plugins are allowed for all tests. Call this to explicitly + // disable them. + void DisallowPlugins() { disallow_plugins_ = true; } // Create a temp file within temp_directory_ with the given name. // The containing directory is also created if necessary. void CreateTempFile(const string& name, const string& contents); + // Create a subdirectory within temp_directory_. + void CreateTempDir(const string& name); + void SetInputsAreProtoPathRelative(bool enable) { cli_.SetInputsAreProtoPathRelative(enable); } @@ -130,7 +126,8 @@ class CommandLineInterfaceTest : public testing::Test { bool HasAlternateErrorSubstring(const string& expected_substring); // Checks that MockCodeGenerator::Generate() was called in the given - // context. That is, this tests if the generator with the given name + // context (or the generator in test_plugin.cc, which produces the same + // output). That is, this tests if the generator with the given name // was called with the given parameter and proto file and produced the // given output file. This is checked by reading the output file and // checking that it contains the content that MockCodeGenerator would @@ -140,8 +137,19 @@ class CommandLineInterfaceTest : public testing::Test { void ExpectGenerated(const string& generator_name, const string& parameter, const string& proto_name, + const string& message_name); + void ExpectGenerated(const string& generator_name, + const string& parameter, + const string& proto_name, const string& message_name, - const string& output_file); + const string& output_directory); + void ExpectGeneratedWithInsertions(const string& generator_name, + const string& parameter, + const string& insertions, + const string& proto_name, + const string& message_name); + + void ExpectNullCodeGeneratorCalled(const string& parameter); void ReadDescriptorSet(const string& filename, FileDescriptorSet* descriptor_set); @@ -150,6 +158,9 @@ class CommandLineInterfaceTest : public testing::Test { // The object we are testing. CommandLineInterface cli_; + // Was DisallowPlugins() called? + bool disallow_plugins_; + // We create a directory within TestTempDir() in order to add extra // protection against accidentally deleting user files (since we recursively // delete this directory during the test). This is the full path of that @@ -164,40 +175,8 @@ class CommandLineInterfaceTest : public testing::Test { // Pointers which need to be deleted later. vector<CodeGenerator*> mock_generators_to_delete_; -}; - -// A mock CodeGenerator which outputs information about the context in which -// it was called, which can then be checked. Output is written to a filename -// constructed by concatenating the filename_prefix (given to the constructor) -// with the proto file name, separated by a '.'. -class CommandLineInterfaceTest::MockCodeGenerator : public CodeGenerator { - public: - // Create a MockCodeGenerator whose Generate() method returns true. - MockCodeGenerator(const string& name, const string& filename_prefix); - - // Create a MockCodeGenerator whose Generate() method returns false - // and sets the error string to the given string. - MockCodeGenerator(const string& name, const string& filename_prefix, - const string& error); - - ~MockCodeGenerator(); - - void set_expect_write_error(bool value) { - expect_write_error_ = value; - } - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const; - - private: - string name_; - string filename_prefix_; - bool return_error_; - string error_; - bool expect_write_error_; + NullCodeGenerator* null_generator_; }; class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { @@ -237,6 +216,22 @@ void CommandLineInterfaceTest::SetUp() { // Create the temp directory. GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE)); + + // Register generators. + CodeGenerator* generator = new MockCodeGenerator("test_generator"); + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator("--test_out", generator, "Test output."); + cli_.RegisterGenerator("-t", generator, "Test output."); + + generator = new MockCodeGenerator("alt_generator"); + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator("--alt_out", generator, "Alt output."); + + generator = null_generator_ = new NullCodeGenerator(); + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator("--null_out", generator, "Null output."); + + disallow_plugins_ = false; } void CommandLineInterfaceTest::TearDown() { @@ -254,6 +249,44 @@ void CommandLineInterfaceTest::Run(const string& command) { vector<string> args; SplitStringUsing(command, " ", &args); + if (!disallow_plugins_) { + cli_.AllowPlugins("prefix-"); + + const char* possible_paths[] = { + // When building with shared libraries, libtool hides the real executable + // in .libs and puts a fake wrapper in the current directory. + // Unfortunately, due to an apparent bug on Cygwin/MinGW, if one program + // wrapped in this way (e.g. protobuf-tests.exe) tries to execute another + // program wrapped in this way (e.g. test_plugin.exe), the latter fails + // with error code 127 and no explanation message. Presumably the problem + // is that the wrapper for protobuf-tests.exe set some environment + // variables that confuse the wrapper for test_plugin.exe. Luckily, it + // turns out that if we simply invoke the wrapped test_plugin.exe + // directly, it works -- I guess the environment variables set by the + // protobuf-tests.exe wrapper happen to be correct for it too. So we do + // that. + ".libs/test_plugin.exe", // Win32 w/autotool (Cygwin / MinGW) + "test_plugin.exe", // Other Win32 (MSVC) + "test_plugin", // Unix + }; + + string plugin_path; + + for (int i = 0; i < GOOGLE_ARRAYSIZE(possible_paths); i++) { + if (access(possible_paths[i], F_OK) == 0) { + plugin_path = possible_paths[i]; + break; + } + } + + if (plugin_path.empty()) { + GOOGLE_LOG(ERROR) + << "Plugin executable not found. Plugin tests are likely to fail."; + } else { + args.push_back("--plugin=prefix-gen-plug=" + plugin_path); + } + } + scoped_array<const char*> argv(new const char*[args.size()]); for (int i = 0; i < args.size(); i++) { @@ -270,44 +303,6 @@ void CommandLineInterfaceTest::Run(const string& command) { // ------------------------------------------------------------------- -CommandLineInterfaceTest::MockCodeGenerator* -CommandLineInterfaceTest::RegisterGenerator( - const string& generator_name, - const string& flag_name, - const string& filename, - const string& help_text) { - MockCodeGenerator* generator = - new MockCodeGenerator(generator_name, filename); - mock_generators_to_delete_.push_back(generator); - - cli_.RegisterGenerator(flag_name, generator, help_text); - return generator; -} - -CommandLineInterfaceTest::MockCodeGenerator* -CommandLineInterfaceTest::RegisterErrorGenerator( - const string& generator_name, - const string& error_text, - const string& flag_name, - const string& filename_prefix, - const string& help_text) { - MockCodeGenerator* generator = - new MockCodeGenerator(generator_name, filename_prefix, error_text); - mock_generators_to_delete_.push_back(generator); - - cli_.RegisterGenerator(flag_name, generator, help_text); - return generator; -} - -CommandLineInterfaceTest::NullCodeGenerator* -CommandLineInterfaceTest::RegisterNullGenerator( - const string& flag_name) { - NullCodeGenerator* generator = new NullCodeGenerator; - mock_generators_to_delete_.push_back(generator); - cli_.RegisterGenerator(flag_name, generator, ""); - return generator; -} - void CommandLineInterfaceTest::CreateTempFile( const string& name, const string& contents) { @@ -323,6 +318,10 @@ void CommandLineInterfaceTest::CreateTempFile( File::WriteStringToFileOrDie(contents, full_name); } +void CommandLineInterfaceTest::CreateTempDir(const string& name) { + File::RecursivelyCreateDir(temp_directory_ + "/" + name, 0777); +} + // ------------------------------------------------------------------- void CommandLineInterfaceTest::ExpectNoErrors() { @@ -352,21 +351,37 @@ void CommandLineInterfaceTest::ExpectGenerated( const string& generator_name, const string& parameter, const string& proto_name, + const string& message_name) { + MockCodeGenerator::ExpectGenerated( + generator_name, parameter, "", proto_name, message_name, temp_directory_); +} + +void CommandLineInterfaceTest::ExpectGenerated( + const string& generator_name, + const string& parameter, + const string& proto_name, const string& message_name, - const string& output_file_prefix) { - // Open and read the file. - string output_file = output_file_prefix + "." + proto_name; - string file_contents; - ASSERT_TRUE(File::ReadFileToString(temp_directory_ + "/" + output_file, - &file_contents)) - << "Failed to open file: " + output_file; + const string& output_directory) { + MockCodeGenerator::ExpectGenerated( + generator_name, parameter, "", proto_name, message_name, + temp_directory_ + "/" + output_directory); +} - // Check that the contents are as we expect. - string expected_contents = - generator_name + ": " + parameter + ", " + proto_name + ", " + - message_name + "\n"; - EXPECT_EQ(expected_contents, file_contents) - << "Output file did not have expected contents: " + output_file; +void CommandLineInterfaceTest::ExpectGeneratedWithInsertions( + const string& generator_name, + const string& parameter, + const string& insertions, + const string& proto_name, + const string& message_name) { + MockCodeGenerator::ExpectGenerated( + generator_name, parameter, insertions, proto_name, message_name, + temp_directory_); +} + +void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled( + const string& parameter) { + EXPECT_TRUE(null_generator_->called_); + EXPECT_EQ(parameter, null_generator_->parameter_); } void CommandLineInterfaceTest::ReadDescriptorSet( @@ -383,77 +398,52 @@ void CommandLineInterfaceTest::ReadDescriptorSet( // =================================================================== -CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator( - const string& name, const string& filename_prefix) - : name_(name), - filename_prefix_(filename_prefix), - return_error_(false), - expect_write_error_(false) { -} - -CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator( - const string& name, const string& filename_prefix, const string& error) - : name_(name), - filename_prefix_(filename_prefix), - return_error_(true), - error_(error), - expect_write_error_(false) { -} +TEST_F(CommandLineInterfaceTest, BasicOutput) { + // Test that the common case works. -CommandLineInterfaceTest::MockCodeGenerator::~MockCodeGenerator() {} + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); -bool CommandLineInterfaceTest::MockCodeGenerator::Generate( - const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(filename_prefix_ + "." + file->name())); - io::Printer printer(output.get(), '$'); - map<string, string> vars; - vars["name"] = name_; - vars["parameter"] = parameter; - vars["proto_name"] = file->name(); - vars["message_name"] = file->message_type_count() > 0 ? - file->message_type(0)->full_name().c_str() : "(none)"; - - printer.Print(vars, "$name$: $parameter$, $proto_name$, $message_name$\n"); - - if (expect_write_error_) { - EXPECT_TRUE(printer.failed()); - } else { - EXPECT_FALSE(printer.failed()); - } + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); - *error = error_; - return !return_error_; + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } -// =================================================================== +TEST_F(CommandLineInterfaceTest, BasicPlugin) { + // Test that basic plugins work. -TEST_F(CommandLineInterfaceTest, BasicOutput) { - // Test that the common case works. + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); +} - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); +TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) { + // Invoke a generator and a plugin at the same time. CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); - Run("protocol_compiler --test_out=$tmpdir " + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, MultipleInputs) { // Test parsing multiple input files. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -461,48 +451,68 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) { "syntax = \"proto2\";\n" "message Bar {}\n"); - Run("protocol_compiler --test_out=$tmpdir " + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " "--proto_path=$tmpdir foo.proto bar.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); - ExpectGenerated("test_generator", "", "bar.proto", "Bar", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); + ExpectGenerated("test_generator", "", "bar.proto", "Bar"); } TEST_F(CommandLineInterfaceTest, CreateDirectory) { // Test that when we output to a sub-directory, it is created. - RegisterGenerator("test_generator", "--test_out", - "bar/baz/output.test", "Test output."); - - CreateTempFile("foo.proto", + CreateTempFile("bar/baz/foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); + CreateTempDir("out"); + CreateTempDir("plugout"); - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); + Run("protocol_compiler --test_out=$tmpdir/out --plug_out=$tmpdir/plugout " + "--proto_path=$tmpdir bar/baz/foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", - "foo.proto", "Foo", "bar/baz/output.test"); + ExpectGenerated("test_generator", "", "bar/baz/foo.proto", "Foo", "out"); + ExpectGenerated("test_plugin", "", "bar/baz/foo.proto", "Foo", "plugout"); } TEST_F(CommandLineInterfaceTest, GeneratorParameters) { // Test that generator parameters are correctly parsed from the command line. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); Run("protocol_compiler --test_out=TestParameter:$tmpdir " + "--plug_out=TestPluginParameter:$tmpdir " "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "TestParameter", - "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "TestParameter", "foo.proto", "Foo"); + ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo"); +} + +TEST_F(CommandLineInterfaceTest, Insert) { + // Test running a generator that inserts code into another's output. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler " + "--test_out=TestParameter:$tmpdir " + "--plug_out=TestPluginParameter:$tmpdir " + "--test_out=insert=test_generator,test_plugin:$tmpdir " + "--plug_out=insert=test_generator,test_plugin:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGeneratedWithInsertions( + "test_generator", "TestParameter", "test_generator,test_plugin", + "foo.proto", "Foo"); + ExpectGeneratedWithInsertions( + "test_plugin", "TestPluginParameter", "test_generator,test_plugin", + "foo.proto", "Foo"); } #if defined(_WIN32) || defined(__CYGWIN__) @@ -510,42 +520,33 @@ TEST_F(CommandLineInterfaceTest, GeneratorParameters) { TEST_F(CommandLineInterfaceTest, WindowsOutputPath) { // Test that the output path can be a Windows-style path. - NullCodeGenerator* generator = RegisterNullGenerator("--test_out"); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n"); - Run("protocol_compiler --test_out=C:\\ " + Run("protocol_compiler --null_out=C:\\ " "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - EXPECT_TRUE(generator->called_); - EXPECT_EQ("", generator->parameter_); + ExpectNullCodeGeneratorCalled(""); } TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) { // Test that we can have a windows-style output path and a parameter. - NullCodeGenerator* generator = RegisterNullGenerator("--test_out"); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n"); - Run("protocol_compiler --test_out=bar:C:\\ " + Run("protocol_compiler --null_out=bar:C:\\ " "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - EXPECT_TRUE(generator->called_); - EXPECT_EQ("bar", generator->parameter_); + ExpectNullCodeGeneratorCalled("bar"); } TEST_F(CommandLineInterfaceTest, TrailingBackslash) { // Test that the directories can end in backslashes. Some users claim this // doesn't work on their system. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -554,7 +555,7 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) { "--proto_path=$tmpdir\\ foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } #endif // defined(_WIN32) || defined(__CYGWIN__) @@ -562,9 +563,6 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) { TEST_F(CommandLineInterfaceTest, PathLookup) { // Test that specifying multiple directories in the proto search path works. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("b/bar.proto", "syntax = \"proto2\";\n" "message Bar {}\n"); @@ -580,15 +578,12 @@ TEST_F(CommandLineInterfaceTest, PathLookup) { "--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) { // Same as PathLookup, but we provide the proto_path in a single flag. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("b/bar.proto", "syntax = \"proto2\";\n" "message Bar {}\n"); @@ -613,15 +608,12 @@ TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) { #undef PATH_SEPARATOR ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, NonRootMapping) { // Test setting up a search path mapping a directory to a non-root location. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -630,42 +622,34 @@ TEST_F(CommandLineInterfaceTest, NonRootMapping) { "--proto_path=bar=$tmpdir bar/foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, MultipleGenerators) { // Test that we can have multiple generators and use both in one invocation, // each with a different output directory. - RegisterGenerator("test_generator_1", "--test1_out", - "output1.test", "Test output 1."); - RegisterGenerator("test_generator_2", "--test2_out", - "output2.test", "Test output 2."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); // Create the "a" and "b" sub-directories. - CreateTempFile("a/dummy", ""); - CreateTempFile("b/dummy", ""); + CreateTempDir("a"); + CreateTempDir("b"); Run("protocol_compiler " - "--test1_out=$tmpdir/a " - "--test2_out=$tmpdir/b " + "--test_out=$tmpdir/a " + "--alt_out=$tmpdir/b " "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator_1", "", "foo.proto", "Foo", "a/output1.test"); - ExpectGenerated("test_generator_2", "", "foo.proto", "Foo", "b/output2.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo", "a"); + ExpectGenerated("alt_generator", "", "foo.proto", "Foo", "b"); } TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) { // Test that --disallow_services doesn't cause a problem when there are no // services. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -674,15 +658,12 @@ TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) { "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) { // Test that --disallow_services produces an error when there are services. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n" @@ -697,9 +678,6 @@ TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) { TEST_F(CommandLineInterfaceTest, AllowServicesHasService) { // Test that services work fine as long as --disallow_services is not used. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n" @@ -709,7 +687,7 @@ TEST_F(CommandLineInterfaceTest, AllowServicesHasService) { "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { @@ -717,9 +695,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { SetInputsAreProtoPathRelative(false); - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -728,7 +703,7 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { "--proto_path=$tmpdir $tmpdir/foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) { @@ -775,8 +750,8 @@ TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) { if (HasFatalFailure()) return; ASSERT_EQ(2, descriptor_set.file_size()); if (descriptor_set.file(0).name() == "bar.proto") { - swap(descriptor_set.mutable_file()->mutable_data()[0], - descriptor_set.mutable_file()->mutable_data()[1]); + std::swap(descriptor_set.mutable_file()->mutable_data()[0], + descriptor_set.mutable_file()->mutable_data()[1]); } EXPECT_EQ("foo.proto", descriptor_set.file(0).name()); EXPECT_EQ("bar.proto", descriptor_set.file(1).name()); @@ -787,9 +762,6 @@ TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) { TEST_F(CommandLineInterfaceTest, ParseErrors) { // Test that parse errors are reported. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "badsyntax\n"); @@ -804,9 +776,6 @@ TEST_F(CommandLineInterfaceTest, ParseErrors) { TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) { // Test that parse errors are reported from multiple files. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - // We set up files such that foo.proto actually depends on bar.proto in // two ways: Directly and through baz.proto. bar.proto's errors should // only be reported once. @@ -834,9 +803,6 @@ TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) { TEST_F(CommandLineInterfaceTest, InputNotFoundError) { // Test what happens if the input file is not found. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir foo.proto"); @@ -850,9 +816,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) { SetInputsAreProtoPathRelative(false); - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir $tmpdir/foo.proto"); @@ -866,9 +829,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) { SetInputsAreProtoPathRelative(false); - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -882,7 +842,11 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) { ExpectErrorText( "$tmpdir/foo.proto: File does not reside within any path " "specified using --proto_path (or -I). You must specify a " - "--proto_path which encompasses this file.\n"); + "--proto_path which encompasses this file. Note that the " + "proto_path must be an exact prefix of the .proto file " + "names -- protoc is too dumb to figure out when two paths " + "(e.g. absolute and relative) are equivalent (it's harder " + "than you think).\n"); } TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) { @@ -891,9 +855,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) { SetInputsAreProtoPathRelative(false); - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - // Create a directory called "bar" so that we can point --proto_path at it. CreateTempFile("bar/dummy", ""); @@ -910,9 +871,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) { SetInputsAreProtoPathRelative(false); - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo/foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -934,9 +892,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) { TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) { // Test what happens if the input file is not found. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir/foo foo.proto"); @@ -948,9 +903,6 @@ TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) { TEST_F(CommandLineInterfaceTest, MissingInputError) { // Test that we get an error if no inputs are given. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir"); @@ -958,9 +910,6 @@ TEST_F(CommandLineInterfaceTest, MissingInputError) { } TEST_F(CommandLineInterfaceTest, MissingOutputError) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -971,35 +920,59 @@ TEST_F(CommandLineInterfaceTest, MissingOutputError) { } TEST_F(CommandLineInterfaceTest, OutputWriteError) { - MockCodeGenerator* generator = - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - generator->set_expect_write_error(true); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); + string output_file = + MockCodeGenerator::GetOutputFileName("test_generator", "foo.proto"); + // Create a directory blocking our output location. - CreateTempFile("output.test.foo.proto/foo", ""); + CreateTempDir(output_file); Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir foo.proto"); + // MockCodeGenerator no longer detects an error because we actually write to + // an in-memory location first, then dump to disk at the end. This is no + // big deal. + // ExpectErrorSubstring("MockCodeGenerator detected write error."); + #if defined(_WIN32) && !defined(__CYGWIN__) // Windows with MSVCRT.dll produces EPERM instead of EISDIR. - if (HasAlternateErrorSubstring("output.test.foo.proto: Permission denied")) { + if (HasAlternateErrorSubstring(output_file + ": Permission denied")) { return; } #endif - ExpectErrorSubstring("output.test.foo.proto: Is a directory"); + ExpectErrorSubstring(output_file + ": Is a directory"); } -TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); +TEST_F(CommandLineInterfaceTest, PluginOutputWriteError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + string output_file = + MockCodeGenerator::GetOutputFileName("test_plugin", "foo.proto"); + // Create a directory blocking our output location. + CreateTempDir(output_file); + + Run("protocol_compiler --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + +#if defined(_WIN32) && !defined(__CYGWIN__) + // Windows with MSVCRT.dll produces EPERM instead of EISDIR. + if (HasAlternateErrorSubstring(output_file + ": Permission denied")) { + return; + } +#endif + + ExpectErrorSubstring(output_file + ": Is a directory"); +} + +TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) { CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1007,14 +980,21 @@ TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) { Run("protocol_compiler --test_out=$tmpdir/nosuchdir " "--proto_path=$tmpdir foo.proto"); - ExpectErrorSubstring("nosuchdir/: " - "No such file or directory"); + ExpectErrorSubstring("nosuchdir/: No such file or directory"); } -TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); +TEST_F(CommandLineInterfaceTest, PluginOutputDirectoryNotFoundError) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --plug_out=$tmpdir/nosuchdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("nosuchdir/: No such file or directory"); +} +TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) { CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1033,45 +1013,124 @@ TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) { } TEST_F(CommandLineInterfaceTest, GeneratorError) { - RegisterErrorGenerator("error_generator", "Test error message.", - "--error_out", "output.test", "Test error output."); + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Error {}\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring( + "--test_out: foo.proto: Saw message type MockCodeGenerator_Error."); +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginError) { + // Test a generator plugin that returns an error. CreateTempFile("foo.proto", "syntax = \"proto2\";\n" - "message Foo {}\n"); + "message MockCodeGenerator_Error {}\n"); - Run("protocol_compiler --error_out=$tmpdir " + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " "--proto_path=$tmpdir foo.proto"); - ExpectErrorSubstring("--error_out: Test error message."); + ExpectErrorSubstring( + "--plug_out: foo.proto: Saw message type MockCodeGenerator_Error."); } -TEST_F(CommandLineInterfaceTest, HelpText) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - RegisterErrorGenerator("error_generator", "Test error message.", - "--error_out", "output.test", "Test error output."); +TEST_F(CommandLineInterfaceTest, GeneratorPluginFail) { + // Test a generator plugin that exits with an error code. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Exit {}\n"); + + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("Saw message type MockCodeGenerator_Exit."); + ExpectErrorSubstring( + "--plug_out: prefix-gen-plug: Plugin failed with status code 123."); +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) { + // Test a generator plugin that crashes. CreateTempFile("foo.proto", "syntax = \"proto2\";\n" + "message MockCodeGenerator_Abort {}\n"); + + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("Saw message type MockCodeGenerator_Abort."); + +#ifdef _WIN32 + // Windows doesn't have signals. It looks like abort()ing causes the process + // to exit with status code 3, but let's not depend on the exact number here. + ExpectErrorSubstring( + "--plug_out: prefix-gen-plug: Plugin failed with status code"); +#else + // Don't depend on the exact signal number. + ExpectErrorSubstring( + "--plug_out: prefix-gen-plug: Plugin killed by signal"); +#endif +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) { + // Test what happens if the plugin isn't found. + + CreateTempFile("error.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --badplug_out=TestParameter:$tmpdir " + "--plugin=prefix-gen-badplug=no_such_file " + "--proto_path=$tmpdir error.proto"); + +#ifdef _WIN32 + ExpectErrorSubstring( + "--badplug_out: prefix-gen-badplug: The system cannot find the file " + "specified."); +#else + // Error written to stdout by child process after exec() fails. + ExpectErrorSubstring( + "no_such_file: program not found or is not executable"); + + // Error written by parent process when child fails. + ExpectErrorSubstring( + "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1."); +#endif +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) { + // Test what happens if plugins aren't allowed. + + CreateTempFile("error.proto", + "syntax = \"proto2\";\n" "message Foo {}\n"); + DisallowPlugins(); + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir error.proto"); + + ExpectErrorSubstring("Unknown flag: --plug_out"); +} + +TEST_F(CommandLineInterfaceTest, HelpText) { Run("test_exec_name --help"); ExpectErrorSubstring("Usage: test_exec_name "); ExpectErrorSubstring("--test_out=OUT_DIR"); ExpectErrorSubstring("Test output."); - ExpectErrorSubstring("--error_out=OUT_DIR"); - ExpectErrorSubstring("Test error output."); + ExpectErrorSubstring("--alt_out=OUT_DIR"); + ExpectErrorSubstring("Alt output."); } TEST_F(CommandLineInterfaceTest, GccFormatErrors) { // Test --error_format=gcc (which is the default, but we want to verify // that it can be set explicitly). - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "badsyntax\n"); @@ -1086,9 +1145,6 @@ TEST_F(CommandLineInterfaceTest, GccFormatErrors) { TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) { // Test --error_format=msvs - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "badsyntax\n"); @@ -1104,9 +1160,6 @@ TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) { TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) { // Test --error_format=msvs - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "badsyntax\n"); @@ -1124,9 +1177,6 @@ TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) { TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) { // Test that a single-character flag works. - RegisterGenerator("test_generator", "-t", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1135,15 +1185,12 @@ TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) { "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) { // Test that separating the flag value with a space works. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1152,16 +1199,13 @@ TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) { "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) { // Test that separating the flag value with a space works for // single-character flags. - RegisterGenerator("test_generator", "-t", - "output.test", "Test output."); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1170,15 +1214,12 @@ TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) { "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } TEST_F(CommandLineInterfaceTest, MissingValueError) { // Test that we get an error if a flag is missing its value. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto"); ExpectErrorText("Missing value for flag: --test_out\n"); @@ -1188,9 +1229,6 @@ TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) { // Test that we get an error if the last argument is a flag requiring a // value. - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - Run("protocol_compiler --test_out"); ExpectErrorText("Missing value for flag: --test_out\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index a7bc35b..30b1d2b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -123,8 +123,11 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { Importer importer(&source_tree, &error_collector); const FileDescriptor* proto_file = importer.Import("google/protobuf/descriptor.proto"); + const FileDescriptor* plugin_proto_file = + importer.Import("google/protobuf/compiler/plugin.proto"); EXPECT_EQ("", error_collector.text_); ASSERT_TRUE(proto_file != NULL); + ASSERT_TRUE(plugin_proto_file != NULL); CppGenerator generator; MockOutputDirectory output_directory; @@ -133,11 +136,18 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { parameter = "dllexport_decl=LIBPROTOBUF_EXPORT"; ASSERT_TRUE(generator.Generate(proto_file, parameter, &output_directory, &error)); + parameter = "dllexport_decl=LIBPROTOC_EXPORT"; + ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter, + &output_directory, &error)); output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.h", "google/protobuf/descriptor.pb.h"); output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.cc", "google/protobuf/descriptor.pb.cc"); + output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h", + "google/protobuf/compiler/plugin.pb.h"); + output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", + "google/protobuf/compiler/plugin.pb.cc"); } } // namespace @@ -145,5 +155,4 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { } // namespace cpp } // namespace compiler } // namespace protobuf - } // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 90e9172..76d2b79 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -98,6 +98,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { "$dllexport$bool $classname$_IsValid(int value);\n" "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n" + "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n" "\n"); if (HasDescriptorMethods(descriptor_->file())) { @@ -149,17 +150,21 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { "static const $nested_name$ $nested_name$_MIN =\n" " $classname$_$nested_name$_MIN;\n" "static const $nested_name$ $nested_name$_MAX =\n" - " $classname$_$nested_name$_MAX;\n"); + " $classname$_$nested_name$_MAX;\n" + "static const int $nested_name$_ARRAYSIZE =\n" + " $classname$_$nested_name$_ARRAYSIZE;\n"); if (HasDescriptorMethods(descriptor_->file())) { printer->Print(vars, "static inline const ::google::protobuf::EnumDescriptor*\n" "$nested_name$_descriptor() {\n" " return $classname$_descriptor();\n" - "}\n" + "}\n"); + printer->Print(vars, "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n" " return $classname$_Name(value);\n" - "}\n" + "}\n"); + printer->Print(vars, "static inline bool $nested_name$_Parse(const ::std::string& name,\n" " $nested_name$* value) {\n" " return $classname$_Parse(name, value);\n" @@ -240,7 +245,8 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) { } printer->Print(vars, "const $classname$ $parent$::$nested_name$_MIN;\n" - "const $classname$ $parent$::$nested_name$_MAX;\n"); + "const $classname$ $parent$::$nested_name$_MAX;\n" + "const int $parent$::$nested_name$_ARRAYSIZE;\n"); printer->Print("#endif // _MSC_VER\n"); } diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 7ca11c8..91ce493 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -114,7 +114,9 @@ void EnumFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { printer->Print(variables_, "int value;\n" - "DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value));\n" + "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" + " input, &value)));\n" "if ($type$_IsValid(value)) {\n" " set_$name$(static_cast< $type$ >(value));\n"); if (HasUnknownFields(descriptor_->file())) { @@ -170,24 +172,17 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n" - "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n" "inline $type$ $name$(int index) const$deprecation$;\n" "inline void set_$name$(int index, $type$ value)$deprecation$;\n" "inline void add_$name$($type$ value)$deprecation$;\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n" + "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n"); } void RepeatedEnumFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedField<int>*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" "inline $type$ $classname$::$name$(int index) const {\n" " return static_cast< $type$ >($name$_.Get(index));\n" "}\n" @@ -199,6 +194,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GOOGLE_DCHECK($type$_IsValid(value));\n" " $name$_.Add(value);\n" "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField<int>&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedField<int>*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); } void RepeatedEnumFieldGenerator:: @@ -223,7 +227,33 @@ GenerateConstructorCode(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { - if (descriptor_->options().packed()) { + // Don't use ReadRepeatedPrimitive here so that the enum can be validated. + printer->Print(variables_, + "int value;\n" + "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" + " input, &value)));\n" + "if ($type$_IsValid(value)) {\n" + " add_$name$(static_cast< $type$ >(value));\n"); + if (HasUnknownFields(descriptor_->file())) { + printer->Print(variables_, + "} else {\n" + " mutable_unknown_fields()->AddVarint($number$, value);\n"); + } + printer->Print("}\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { + if (!descriptor_->options().packed()) { + // We use a non-inlined implementation in this case, since this path will + // rarely be executed. + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n" + " input,\n" + " &$type$_IsValid,\n" + " this->mutable_$name$())));\n"); + } else { printer->Print(variables_, "::google::protobuf::uint32 length;\n" "DO_(input->ReadVarint32(&length));\n" @@ -231,25 +261,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { "input->PushLimit(length);\n" "while (input->BytesUntilLimit() > 0) {\n" " int value;\n" - " DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value));\n" + " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" + " input, &value)));\n" " if ($type$_IsValid(value)) {\n" " add_$name$(static_cast< $type$ >(value));\n" " }\n" "}\n" "input->PopLimit(limit);\n"); - } else { - printer->Print(variables_, - "int value;\n" - "DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value));\n" - "if ($type$_IsValid(value)) {\n" - " add_$name$(static_cast< $type$ >(value));\n"); - if (HasUnknownFields(descriptor_->file())) { - printer->Print(variables_, - "} else {\n" - " mutable_unknown_fields()->AddVarint($number$, value);\n"); - } - printer->Print(variables_, - "}\n"); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h index 20dd57b..0793430 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h @@ -83,6 +83,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const; void GenerateSerializeWithCachedSizes(io::Printer* printer) const; void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; void GenerateByteSize(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index 7208ed3..658a707 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -33,6 +33,7 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include <google/protobuf/compiler/cpp/cpp_extension.h> +#include <map> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/io/printer.h> @@ -43,6 +44,18 @@ namespace protobuf { namespace compiler { namespace cpp { +namespace { + +// Returns the fully-qualified class name of the message that this field +// extends. This function is used in the Google-internal code to handle some +// legacy cases. +string ExtendeeClassName(const FieldDescriptor* descriptor) { + const Descriptor* extendee = descriptor->containing_type(); + return ClassName(extendee, true); +} + +} // anonymous namespace + ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, const string& dllexport_decl) : descriptor_(descriptor), @@ -80,7 +93,7 @@ ExtensionGenerator::~ExtensionGenerator() {} void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) { map<string, string> vars; - vars["extendee" ] = ClassName(descriptor_->containing_type(), true); + vars["extendee" ] = ExtendeeClassName(descriptor_); vars["number" ] = SimpleItoa(descriptor_->number()); vars["type_traits" ] = type_traits_; vars["name" ] = descriptor_->name(); @@ -106,6 +119,7 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) { " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n" " $name$;\n" ); + } void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { @@ -115,7 +129,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { string name = scope + descriptor_->name(); map<string, string> vars; - vars["extendee" ] = ClassName(descriptor_->containing_type(), true); + vars["extendee" ] = ExtendeeClassName(descriptor_); vars["type_traits" ] = type_traits_; vars["name" ] = name; vars["constant_name"] = FieldConstantName(descriptor_); @@ -154,7 +168,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { void ExtensionGenerator::GenerateRegistration(io::Printer* printer) { map<string, string> vars; - vars["extendee" ] = ClassName(descriptor_->containing_type(), true); + vars["extendee" ] = ExtendeeClassName(descriptor_); vars["number" ] = SimpleItoa(descriptor_->number()); vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type())); vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false"; @@ -193,5 +207,4 @@ void ExtensionGenerator::GenerateRegistration(io::Printer* printer) { } // namespace cpp } // namespace compiler } // namespace protobuf - } // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index c546e96..103cac4 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -40,6 +40,7 @@ #include <google/protobuf/compiler/cpp/cpp_message_field.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/strutil.h> @@ -61,11 +62,24 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["tag_size"] = SimpleItoa( WireFormat::TagSize(descriptor->number(), descriptor->type())); (*variables)["deprecation"] = descriptor->options().deprecated() - ? " DEPRECATED_PROTOBUF_FIELD" : ""; + ? " PROTOBUF_DEPRECATED" : ""; + } FieldGenerator::~FieldGenerator() {} +void FieldGenerator:: +GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { + // Reaching here indicates a bug. Cases are: + // - This FieldGenerator should support packing, but this method should be + // overridden. + // - This FieldGenerator doesn't support packing, and this method should + // never have been called. + GOOGLE_LOG(FATAL) << "GenerateMergeFromCodedStreamWithPacking() " + << "called on field generator that does not support packing."; + +} + FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) : descriptor_(descriptor), field_generators_( @@ -82,7 +96,11 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) { case FieldDescriptor::CPPTYPE_MESSAGE: return new RepeatedMessageFieldGenerator(field); case FieldDescriptor::CPPTYPE_STRING: - return new RepeatedStringFieldGenerator(field); + switch (field->options().ctype()) { + default: // RepeatedStringFieldGenerator handles unknown ctypes. + case FieldOptions::STRING: + return new RepeatedStringFieldGenerator(field); + } case FieldDescriptor::CPPTYPE_ENUM: return new RepeatedEnumFieldGenerator(field); default: @@ -93,7 +111,11 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) { case FieldDescriptor::CPPTYPE_MESSAGE: return new MessageFieldGenerator(field); case FieldDescriptor::CPPTYPE_STRING: - return new StringFieldGenerator(field); + switch (field->options().ctype()) { + default: // StringFieldGenerator handles unknown ctypes. + case FieldOptions::STRING: + return new StringFieldGenerator(field); + } case FieldDescriptor::CPPTYPE_ENUM: return new EnumFieldGenerator(field); default: @@ -110,6 +132,7 @@ const FieldGenerator& FieldGeneratorMap::get( return *field_generators_[field->index()]; } + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index 00ec2c7..c303a33 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -118,6 +118,11 @@ class FieldGenerator { // message's MergeFromCodedStream() method. virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0; + // Generate lines to decode this field from a packed value, which will be + // placed inside the message's MergeFromCodedStream() method. + virtual void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) + const; + // Generate lines to serialize this field, which are placed within the // message's SerializeWithCachedSizes() method. virtual void GenerateSerializeWithCachedSizes(io::Printer* printer) const = 0; @@ -153,6 +158,7 @@ class FieldGeneratorMap { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); }; + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 51859bb..80da7e4 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -38,6 +38,7 @@ #include <google/protobuf/compiler/cpp/cpp_extension.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_message.h> +#include <google/protobuf/compiler/cpp/cpp_field.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/stubs/strutil.h> @@ -93,12 +94,14 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { // Generate top of header. printer->Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" "\n" "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n" "#define PROTOBUF_$filename_identifier$__INCLUDED\n" "\n" "#include <string>\n" "\n", + "filename", file_->name(), "filename_identifier", filename_identifier); printer->Print( @@ -132,19 +135,23 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { if (HasDescriptorMethods(file_)) { printer->Print( "#include <google/protobuf/generated_message_reflection.h>\n"); + } - if (file_->service_count() > 0) { - printer->Print( - "#include <google/protobuf/service.h>\n"); - } + if (HasGenericServices(file_)) { + printer->Print( + "#include <google/protobuf/service.h>\n"); } + for (int i = 0; i < file_->dependency_count(); i++) { printer->Print( "#include \"$dependency$.pb.h\"\n", "dependency", StripProto(file_->dependency(i)->name())); } + printer->Print( + "// @@protoc_insertion_point(includes)\n"); + // Open namespace. GenerateNamespaceOpeners(printer); @@ -198,7 +205,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print(kThickSeparator); printer->Print("\n"); - if (HasDescriptorMethods(file_)) { + if (HasGenericServices(file_)) { // Generate service definitions. for (int i = 0; i < file_->service_count(); i++) { if (i > 0) { @@ -232,6 +239,10 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { message_generators_[i]->GenerateInlineMethods(printer); } + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + // Close up namespace. GenerateNamespaceClosers(printer); @@ -255,11 +266,15 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print( "\n" "} // namespace google\n} // namespace protobuf\n" - "#endif // SWIG\n" - "\n"); + "#endif // SWIG\n"); } printer->Print( + "\n" + "// @@protoc_insertion_point(global_scope)\n" + "\n"); + + printer->Print( "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", "filename_identifier", filename_identifier); } @@ -285,6 +300,9 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "#include <google/protobuf/wire_format.h>\n"); } + printer->Print( + "// @@protoc_insertion_point(includes)\n"); + GenerateNamespaceOpeners(printer); if (HasDescriptorMethods(file_)) { @@ -300,10 +318,13 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", "name", ClassName(file_->enum_type(i), false)); } - for (int i = 0; i < file_->service_count(); i++) { - printer->Print( - "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", - "name", file_->service(i)->name()); + + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + printer->Print( + "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", + "name", file_->service(i)->name()); + } } printer->Print( @@ -329,7 +350,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) { message_generators_[i]->GenerateClassMethods(printer); } - if (HasDescriptorMethods(file_)) { + if (HasGenericServices(file_)) { // Generate services. for (int i = 0; i < file_->service_count(); i++) { if (i == 0) printer->Print("\n"); @@ -344,7 +365,15 @@ void FileGenerator::GenerateSource(io::Printer* printer) { extension_generators_[i]->GenerateDefinition(printer); } + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + GenerateNamespaceClosers(printer); + + printer->Print( + "\n" + "// @@protoc_insertion_point(global_scope)\n"); } void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { @@ -397,8 +426,10 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { for (int i = 0; i < file_->enum_type_count(); i++) { enum_generators_[i]->GenerateDescriptorInitializer(printer, i); } - for (int i = 0; i < file_->service_count(); i++) { - service_generators_[i]->GenerateDescriptorInitializer(printer, i); + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + service_generators_[i]->GenerateDescriptorInitializer(printer, i); + } } printer->Outdent(); diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 723a8b4..e3df88b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -32,6 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <limits> #include <vector> #include <google/protobuf/stubs/hash.h> @@ -40,6 +41,7 @@ #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + namespace google { namespace protobuf { namespace compiler { @@ -111,6 +113,7 @@ const char kThinSeparator[] = "// -------------------------------------------------------------------\n"; string ClassName(const Descriptor* descriptor, bool qualified) { + // Find "outer", the descriptor of the top-level message in which // "descriptor" is embedded. const Descriptor* outer = descriptor; @@ -141,6 +144,12 @@ string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) { } } + +string SuperClassName(const Descriptor* descriptor) { + return HasDescriptorMethods(descriptor->file()) ? + "::google::protobuf::Message" : "::google::protobuf::MessageLite"; +} + string FieldName(const FieldDescriptor* field) { string result = field->name(); LowerString(&result); @@ -166,6 +175,12 @@ string FieldConstantName(const FieldDescriptor *field) { return result; } +string FieldMessageTypeName(const FieldDescriptor* field) { + // Note: The Google-internal version of Protocol Buffers uses this function + // as a hook point for hacks to support legacy code. + return ClassName(field->message_type(), true); +} + string StripProto(const string& filename) { if (HasSuffixString(filename, ".protodevel")) { return StripSuffixString(filename, ".protodevel"); @@ -235,17 +250,37 @@ string DefaultValue(const FieldDescriptor* field) { return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")"; case FieldDescriptor::CPPTYPE_UINT64: return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field->default_value_double()); + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value = field->default_value_double(); + if (value == numeric_limits<double>::infinity()) { + return "::google::protobuf::internal::Infinity()"; + } else if (value == -numeric_limits<double>::infinity()) { + return "-::google::protobuf::internal::Infinity()"; + } else if (value != value) { + return "::google::protobuf::internal::NaN()"; + } else { + return SimpleDtoa(value); + } + } case FieldDescriptor::CPPTYPE_FLOAT: { - // If floating point value contains a period (.) or an exponent (either - // E or e), then append suffix 'f' to make it a floating-point literal. - string float_value = SimpleFtoa(field->default_value_float()); - if (float_value.find_first_of(".eE") != string::npos) { - float_value.push_back('f'); + float value = field->default_value_float(); + if (value == numeric_limits<float>::infinity()) { + return "static_cast<float>(::google::protobuf::internal::Infinity())"; + } else if (value == -numeric_limits<float>::infinity()) { + return "static_cast<float>(-::google::protobuf::internal::Infinity())"; + } else if (value != value) { + return "static_cast<float>(::google::protobuf::internal::NaN())"; + } else { + string float_value = SimpleFtoa(value); + // If floating point value contains a period (.) or an exponent + // (either E or e), then append suffix 'f' to make it a float + // literal. + if (float_value.find_first_of(".eE") != string::npos) { + float_value.push_back('f'); + } + return float_value; } - return float_value; } case FieldDescriptor::CPPTYPE_BOOL: return field->default_value_bool() ? "true" : "false"; @@ -259,7 +294,7 @@ string DefaultValue(const FieldDescriptor* field) { case FieldDescriptor::CPPTYPE_STRING: return "\"" + CEscape(field->default_value_string()) + "\""; case FieldDescriptor::CPPTYPE_MESSAGE: - return ClassName(field->message_type(), true) + "::default_instance()"; + return FieldMessageTypeName(field) + "::default_instance()"; } // Can't actually get here; make compiler happy. (We could add a default // case above but then we wouldn't get the nice compiler warning when a diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 83e1250..f99b5fe 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -60,6 +60,8 @@ extern const char kThinSeparator[]; string ClassName(const Descriptor* descriptor, bool qualified); string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); +string SuperClassName(const Descriptor* descriptor); + // Get the (unqualified) name that should be used for this field in C++ code. // The name is coerced to lower-case to emulate proto1 behavior. People // should be using lowercase-with-underscores style for proto field names @@ -77,6 +79,10 @@ inline const Descriptor* FieldScope(const FieldDescriptor* field) { field->extension_scope() : field->containing_type(); } +// Returns the fully-qualified type name field->message_type(). Usually this +// is just ClassName(field->message_type(), true); +string FieldMessageTypeName(const FieldDescriptor* field); + // Strips ".proto" or ".protodevel" from the end of a filename. string StripProto(const string& filename); @@ -107,33 +113,41 @@ string GlobalAssignDescriptorsName(const string& filename); string GlobalShutdownFileName(const string& filename); // Do message classes in this file keep track of unknown fields? -inline const bool HasUnknownFields(const FileDescriptor *file) { +inline bool HasUnknownFields(const FileDescriptor *file) { return file->options().optimize_for() != FileOptions::LITE_RUNTIME; } // Does this file have generated parsing, serialization, and other // standard methods for which reflection-based fallback implementations exist? -inline const bool HasGeneratedMethods(const FileDescriptor *file) { +inline bool HasGeneratedMethods(const FileDescriptor *file) { return file->options().optimize_for() != FileOptions::CODE_SIZE; } // Do message classes in this file have descriptor and refelction methods? -inline const bool HasDescriptorMethods(const FileDescriptor *file) { +inline bool HasDescriptorMethods(const FileDescriptor *file) { return file->options().optimize_for() != FileOptions::LITE_RUNTIME; } +// Should we generate generic services for this file? +inline bool HasGenericServices(const FileDescriptor *file) { + return file->service_count() > 0 && + file->options().optimize_for() != FileOptions::LITE_RUNTIME && + file->options().cc_generic_services(); +} + // Should string fields in this file verify that their contents are UTF-8? -inline const bool HasUtf8Verification(const FileDescriptor* file) { +inline bool HasUtf8Verification(const FileDescriptor* file) { return file->options().optimize_for() != FileOptions::LITE_RUNTIME; } // Should we generate a separate, super-optimized code path for serializing to // flat arrays? We don't do this in Lite mode because we'd rather reduce code // size. -inline const bool HasFastArraySerialization(const FileDescriptor* file) { +inline bool HasFastArraySerialization(const FileDescriptor* file) { return file->options().optimize_for() == FileOptions::SPEED; } + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index ae243dd..cbdcce8 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -308,11 +308,10 @@ GenerateClassDefinition(io::Printer* printer) { } else { vars["dllexport"] = dllexport_decl_ + " "; } - vars["superclass"] = HasDescriptorMethods(descriptor_->file()) ? - "Message" : "MessageLite"; + vars["superclass"] = SuperClassName(descriptor_); printer->Print(vars, - "class $dllexport$$classname$ : public ::google::protobuf::$superclass$ {\n" + "class $dllexport$$classname$ : public $superclass$ {\n" " public:\n"); printer->Indent(); @@ -349,6 +348,10 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print(vars, "static const $classname$& default_instance();\n" + "\n"); + + + printer->Print(vars, "void Swap($classname$* other);\n" "\n" "// implements Message ----------------------------------------------\n" @@ -387,7 +390,7 @@ GenerateClassDefinition(io::Printer* printer) { "private:\n" "void SharedCtor();\n" "void SharedDtor();\n" - "void SetCachedSize(int size) const { _cached_size_ = size; }\n" + "void SetCachedSize(int size) const;\n" "public:\n" "\n"); @@ -436,6 +439,11 @@ GenerateClassDefinition(io::Printer* printer) { extension_generators_[i]->GenerateDeclaration(printer); } + + printer->Print( + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + // Generate private members for fields. printer->Outdent(); printer->Print(" private:\n"); @@ -623,6 +631,7 @@ GenerateDefaultInstanceAllocator(io::Printer* printer) { for (int i = 0; i < descriptor_->nested_type_count(); i++) { nested_generators_[i]->GenerateDefaultInstanceAllocator(printer); } + } void MessageGenerator:: @@ -751,6 +760,7 @@ GenerateClassMethods(io::Printer* printer) { "classname", classname_, "type_name", descriptor_->full_name()); } + } void MessageGenerator:: @@ -833,12 +843,16 @@ GenerateSharedDestructorCode(io::Printer* printer) { void MessageGenerator:: GenerateStructors(io::Printer* printer) { + string superclass = SuperClassName(descriptor_); + // Generate the default constructor. printer->Print( - "$classname$::$classname$() {\n" + "$classname$::$classname$()\n" + " : $superclass$() {\n" " SharedCtor();\n" "}\n", - "classname", classname_); + "classname", classname_, + "superclass", superclass); printer->Print( "\n" @@ -859,7 +873,7 @@ GenerateStructors(io::Printer* printer) { printer->Print( " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", "name", FieldName(field), - "type", ClassName(field->message_type(), true)); + "type", FieldMessageTypeName(field)); } } printer->Print( @@ -868,12 +882,14 @@ GenerateStructors(io::Printer* printer) { // Generate the copy constructor. printer->Print( - "$classname$::$classname$(const $classname$& from) {\n" + "$classname$::$classname$(const $classname$& from)\n" + " : $superclass$() {\n" " SharedCtor();\n" " MergeFrom(from);\n" "}\n" "\n", - "classname", classname_); + "classname", classname_, + "superclass", superclass); // Generate the shared constructor code. GenerateSharedConstructorCode(printer); @@ -889,6 +905,15 @@ GenerateStructors(io::Printer* printer) { // Generate the shared destructor code. GenerateSharedDestructorCode(printer); + // Generate SetCachedSize. + printer->Print( + "void $classname$::SetCachedSize(int size) const {\n" + " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" + " _cached_size_ = size;\n" + " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" + "}\n", + "classname", classname_); + // Only generate this member if it's not disabled. if (HasDescriptorMethods(descriptor_->file()) && !descriptor_->options().no_standard_descriptor_accessor()) { @@ -917,6 +942,7 @@ GenerateStructors(io::Printer* printer) { "classname", classname_, "adddescriptorsname", GlobalAddDescriptorsName(descriptor_->file()->name())); + } void MessageGenerator:: @@ -1230,12 +1256,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) { PrintFieldComment(printer, field); printer->Print( - "case $number$: {\n" - " if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) !=\n" - " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n" - " goto handle_uninterpreted;\n" - " }\n", - "number", SimpleItoa(field->number()), + "case $number$: {\n", + "number", SimpleItoa(field->number())); + printer->Indent(); + const FieldGenerator& field_generator = field_generators_.get(field); + + // Emit code to parse the common, expected case. + printer->Print( + "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n", "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]); if (i > 0 || (field->is_repeated() && !field->options().packed())) { @@ -1245,8 +1274,38 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } printer->Indent(); + if (field->options().packed()) { + field_generator.GenerateMergeFromCodedStreamWithPacking(printer); + } else { + field_generator.GenerateMergeFromCodedStream(printer); + } + printer->Outdent(); - field_generators_.get(field).GenerateMergeFromCodedStream(printer); + // Emit code to parse unexpectedly packed or unpacked values. + if (field->is_packable() && field->options().packed()) { + printer->Print( + "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" + " == ::google::protobuf::internal::WireFormatLite::\n" + " WIRETYPE_$wiretype$) {\n", + "wiretype", + kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]); + printer->Indent(); + field_generator.GenerateMergeFromCodedStream(printer); + printer->Outdent(); + } else if (field->is_packable() && !field->options().packed()) { + printer->Print( + "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" + " == ::google::protobuf::internal::WireFormatLite::\n" + " WIRETYPE_LENGTH_DELIMITED) {\n"); + printer->Indent(); + field_generator.GenerateMergeFromCodedStreamWithPacking(printer); + printer->Outdent(); + } + + printer->Print( + "} else {\n" + " goto handle_uninterpreted;\n" + "}\n"); // switch() is slow since it can't be predicted well. Insert some if()s // here that attempt to predict the next tag. @@ -1427,18 +1486,6 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) { "classname", classname_); printer->Indent(); - if (HasFastArraySerialization(descriptor_->file())) { - printer->Print( - "::google::protobuf::uint8* raw_buffer = " - "output->GetDirectBufferForNBytesAndAdvance(_cached_size_);\n" - "if (raw_buffer != NULL) {\n" - " $classname$::SerializeWithCachedSizesToArray(raw_buffer);\n" - " return;\n" - "}\n" - "\n", - "classname", classname_); - } - GenerateSerializeWithCachedSizesBody(printer, false); printer->Outdent(); @@ -1548,7 +1595,9 @@ GenerateByteSize(io::Printer* printer) { " ComputeUnknownMessageSetItemsSize(unknown_fields());\n"); } printer->Print( + " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" " _cached_size_ = total_size;\n" + " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" " return total_size;\n" "}\n"); return; @@ -1640,7 +1689,9 @@ GenerateByteSize(io::Printer* printer) { // exact same value, it works on all common processors. In a future version // of C++, _cached_size_ should be made into an atomic<int>. printer->Print( + "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" "_cached_size_ = total_size;\n" + "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" "return total_size;\n"); printer->Outdent(); @@ -1712,6 +1763,7 @@ GenerateIsInitialized(io::Printer* printer) { "}\n"); } + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index f1c5714..04778f6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -150,6 +150,7 @@ class MessageGenerator { io::Printer* printer, const Descriptor::ExtensionRange* range, bool unbounded); + const Descriptor* descriptor_; string classname_; string dllexport_decl_; diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 059fba6..c04bdc6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -47,7 +47,11 @@ namespace { void SetMessageVariables(const FieldDescriptor* descriptor, map<string, string>* variables) { SetCommonFieldVariables(descriptor, variables); - (*variables)["type"] = ClassName(descriptor->message_type(), true); + (*variables)["type"] = FieldMessageTypeName(descriptor); + (*variables)["stream_writer"] = (*variables)["declared_type"] + + (HasFastArraySerialization(descriptor->message_type()->file()) ? + "MaybeToArray" : + ""); } } // namespace @@ -125,7 +129,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { void MessageFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { printer->Print(variables_, - "::google::protobuf::internal::WireFormatLite::Write$declared_type$NoVirtual(\n" + "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" " $number$, this->$name$(), output);\n"); } @@ -164,26 +168,19 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< $type$ >& $name$() const" - "$deprecation$;\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >* mutable_$name$()" - "$deprecation$;\n" "inline const $type$& $name$(int index) const$deprecation$;\n" "inline $type$* mutable_$name$(int index)$deprecation$;\n" "inline $type$* add_$name$()$deprecation$;\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + " $name$() const$deprecation$;\n" + "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + " mutable_$name$()$deprecation$;\n"); } void RepeatedMessageFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" "inline const $type$& $classname$::$name$(int index) const {\n" " return $name$_.Get(index);\n" "}\n" @@ -193,6 +190,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "inline $type$* $classname$::add_$name$() {\n" " return $name$_.Add();\n" "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); } void RepeatedMessageFieldGenerator:: @@ -232,7 +238,7 @@ void RepeatedMessageFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { printer->Print(variables_, "for (int i = 0; i < this->$name$_size(); i++) {\n" - " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoVirtual(\n" + " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" " $number$, this->$name$(i), output);\n" "}\n"); } diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc new file mode 100644 index 0000000..440b716 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc @@ -0,0 +1,121 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// TODO(kenton): Share code with the versions of this test in other languages? +// It seemed like parameterizing it would add more complexity than it is +// worth. + +#include <google/protobuf/compiler/cpp/cpp_generator.h> +#include <google/protobuf/compiler/command_line_interface.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/printer.h> + +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> +#include <google/protobuf/testing/file.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { +namespace { + +class TestGenerator : public CodeGenerator { + public: + TestGenerator() {} + ~TestGenerator() {} + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const { + TryInsert("test.pb.h", "includes", output_directory); + TryInsert("test.pb.h", "namespace_scope", output_directory); + TryInsert("test.pb.h", "global_scope", output_directory); + TryInsert("test.pb.h", "class_scope:foo.Bar", output_directory); + TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", output_directory); + + TryInsert("test.pb.cc", "includes", output_directory); + TryInsert("test.pb.cc", "namespace_scope", output_directory); + TryInsert("test.pb.cc", "global_scope", output_directory); + return true; + } + + void TryInsert(const string& filename, const string& insertion_point, + OutputDirectory* output_directory) const { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->OpenForInsert(filename, insertion_point)); + io::Printer printer(output.get(), '$'); + printer.Print("// inserted $name$\n", "name", insertion_point); + } +}; + +// This test verifies that all the expected insertion points exist. It does +// not verify that they are correctly-placed; that would require actually +// compiling the output which is a bit more than I care to do for this test. +TEST(CppPluginTest, PluginTest) { + File::WriteStringToFileOrDie( + "syntax = \"proto2\";\n" + "package foo;\n" + "message Bar {\n" + " message Baz {}\n" + "}\n", + TestTempDir() + "/test.proto"); + + google::protobuf::compiler::CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + CppGenerator cpp_generator; + TestGenerator test_generator; + cli.RegisterGenerator("--cpp_out", &cpp_generator, ""); + cli.RegisterGenerator("--test_out", &test_generator, ""); + + string proto_path = "-I" + TestTempDir(); + string cpp_out = "--cpp_out=" + TestTempDir(); + string test_out = "--test_out=" + TestTempDir(); + + const char* argv[] = { + "protoc", + proto_path.c_str(), + cpp_out.c_str(), + test_out.c_str(), + "test.proto" + }; + + EXPECT_EQ(0, cli.Run(5, argv)); +} + +} // namespace +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 81f5ce0..a69c48b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -84,10 +84,14 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, SetCommonFieldVariables(descriptor, variables); (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type()); (*variables)["default"] = DefaultValue(descriptor); + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); int fixed_size = FixedSize(descriptor->type()); if (fixed_size != -1) { (*variables)["fixed_size"] = SimpleItoa(fixed_size); } + (*variables)["wire_format_field_type"] = + "::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name( + static_cast<FieldDescriptorProto_Type>(descriptor->type())); } } // namespace @@ -149,8 +153,9 @@ GenerateConstructorCode(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n" - " input, &$name$_));\n" + "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" + " $type$, $wire_format_field_type$>(\n" + " input, &$name$_)));\n" "_set_bit($index$);\n"); } @@ -188,6 +193,14 @@ RepeatedPrimitiveFieldGenerator:: RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor) : descriptor_(descriptor) { SetPrimitiveVariables(descriptor, &variables_); + + if (descriptor->options().packed()) { + variables_["packed_reader"] = "ReadPackedPrimitive"; + variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline"; + } else { + variables_["packed_reader"] = "ReadPackedPrimitiveNoInline"; + variables_["repeated_reader"] = "ReadRepeatedPrimitive"; + } } RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} @@ -205,25 +218,19 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >& $name$() const\n" - " $deprecation$;\n" - "inline ::google::protobuf::RepeatedField< $type$ >* mutable_$name$()$deprecation$;\n" "inline $type$ $name$(int index) const$deprecation$;\n" "inline void set_$name$(int index, $type$ value)$deprecation$;\n" "inline void add_$name$($type$ value)$deprecation$;\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + " $name$() const$deprecation$;\n" + "inline ::google::protobuf::RepeatedField< $type$ >*\n" + " mutable_$name$()$deprecation$;\n"); } void RepeatedPrimitiveFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedField< $type$ >*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" "inline $type$ $classname$::$name$(int index) const {\n" " return $name$_.Get(index);\n" "}\n" @@ -233,6 +240,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "inline void $classname$::add_$name$($type$ value) {\n" " $name$_.Add(value);\n" "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedField< $type$ >*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); } void RepeatedPrimitiveFieldGenerator:: @@ -257,30 +273,18 @@ GenerateConstructorCode(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { - if (descriptor_->options().packed()) { - printer->Print("{\n"); - printer->Indent(); - printer->Print(variables_, - "::google::protobuf::uint32 length;\n" - "DO_(input->ReadVarint32(&length));\n" - "::google::protobuf::io::CodedInputStream::Limit limit =\n" - " input->PushLimit(length);\n" - "while (input->BytesUntilLimit() > 0) {\n" - " $type$ value;\n" - " DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n" - " input, &value));\n" - " add_$name$(value);\n" - "}\n" - "input->PopLimit(limit);\n"); - printer->Outdent(); - printer->Print("}\n"); - } else { - printer->Print(variables_, - "$type$ value;\n" - "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n" - " input, &value));\n" - "add_$name$(value);\n"); - } + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormatLite::$repeated_reader$<\n" + " $type$, $wire_format_field_type$>(\n" + " $tag_size$, $tag$, input, this->mutable_$name$())));\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormatLite::$packed_reader$<\n" + " $type$, $wire_format_field_type$>(\n" + " input, this->mutable_$name$())));\n"); } void RepeatedPrimitiveFieldGenerator:: diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h index 6b96614..8fcd74a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h @@ -83,6 +83,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; void GenerateMergeFromCodedStream(io::Printer* printer) const; + void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const; void GenerateSerializeWithCachedSizes(io::Printer* printer) const; void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; void GenerateByteSize(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 72258e8..ea6809a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -91,7 +91,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const { // files that applied the ctype. The field can still be accessed via the // reflection interface since the reflection interface is independent of // the string's underlying representation. - if (descriptor_->options().has_ctype()) { + if (descriptor_->options().ctype() != FieldOptions::STRING) { printer->Outdent(); printer->Print( " private:\n" @@ -107,7 +107,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const { "$deprecation$;\n" "inline ::std::string* mutable_$name$()$deprecation$;\n"); - if (descriptor_->options().has_ctype()) { + if (descriptor_->options().ctype() != FieldOptions::STRING) { printer->Outdent(); printer->Print(" public:\n"); printer->Indent(); @@ -278,7 +278,7 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { // See comment above about unknown ctypes. - if (descriptor_->options().has_ctype()) { + if (descriptor_->options().ctype() != FieldOptions::STRING) { printer->Outdent(); printer->Print( " private:\n" @@ -287,10 +287,6 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const" - "$deprecation$;\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" - "$deprecation$;\n" "inline const ::std::string& $name$(int index) const$deprecation$;\n" "inline ::std::string* mutable_$name$(int index)$deprecation$;\n" "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n" @@ -304,7 +300,13 @@ GenerateAccessorDeclarations(io::Printer* printer) const { "inline void add_$name$(const $pointer_type$* value, size_t size)" "$deprecation$;\n"); - if (descriptor_->options().has_ctype()) { + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const" + "$deprecation$;\n" + "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" + "$deprecation$;\n"); + + if (descriptor_->options().ctype() != FieldOptions::STRING) { printer->Outdent(); printer->Print(" public:\n"); printer->Indent(); @@ -314,14 +316,6 @@ GenerateAccessorDeclarations(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" "inline const ::std::string& $classname$::$name$(int index) const {\n" " return $name$_.Get(index);\n" "}\n" @@ -353,6 +347,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n" " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n" "}\n"); + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" + "$classname$::$name$() const {\n" + " return $name$_;\n" + "}\n" + "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n" + "$classname$::mutable_$name$() {\n" + " return &$name$_;\n" + "}\n"); } void RepeatedStringFieldGenerator:: diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index d7575c0..a7e852d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -49,6 +49,7 @@ #include <google/protobuf/unittest.pb.h> #include <google/protobuf/unittest_optimize_for.pb.h> #include <google/protobuf/unittest_embed_optimize_for.pb.h> +#include <google/protobuf/unittest_no_generic_services.pb.h> #include <google/protobuf/test_util.h> #include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h> #include <google/protobuf/compiler/importer.h> @@ -154,6 +155,16 @@ TEST(GeneratedMessageTest, FloatingPointDefaults) { EXPECT_EQ(-1.5f, extreme_default.negative_float()); EXPECT_EQ(2.0e8f, extreme_default.large_float()); EXPECT_EQ(-8e-28f, extreme_default.small_negative_float()); + EXPECT_EQ(numeric_limits<double>::infinity(), + extreme_default.inf_double()); + EXPECT_EQ(-numeric_limits<double>::infinity(), + extreme_default.neg_inf_double()); + EXPECT_TRUE(extreme_default.nan_double() != extreme_default.nan_double()); + EXPECT_EQ(numeric_limits<float>::infinity(), + extreme_default.inf_float()); + EXPECT_EQ(-numeric_limits<float>::infinity(), + extreme_default.neg_inf_float()); + EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float()); } TEST(GeneratedMessageTest, Accessors) { @@ -779,22 +790,39 @@ TEST(GeneratedEnumTest, IsValidValue) { } TEST(GeneratedEnumTest, MinAndMax) { - EXPECT_EQ(unittest::TestAllTypes::FOO,unittest::TestAllTypes::NestedEnum_MIN); - EXPECT_EQ(unittest::TestAllTypes::BAZ,unittest::TestAllTypes::NestedEnum_MAX); + EXPECT_EQ(unittest::TestAllTypes::FOO, + unittest::TestAllTypes::NestedEnum_MIN); + EXPECT_EQ(unittest::TestAllTypes::BAZ, + unittest::TestAllTypes::NestedEnum_MAX); + EXPECT_EQ(4, unittest::TestAllTypes::NestedEnum_ARRAYSIZE); EXPECT_EQ(unittest::FOREIGN_FOO, unittest::ForeignEnum_MIN); EXPECT_EQ(unittest::FOREIGN_BAZ, unittest::ForeignEnum_MAX); + EXPECT_EQ(7, unittest::ForeignEnum_ARRAYSIZE); EXPECT_EQ(1, unittest::TestEnumWithDupValue_MIN); EXPECT_EQ(3, unittest::TestEnumWithDupValue_MAX); + EXPECT_EQ(4, unittest::TestEnumWithDupValue_ARRAYSIZE); EXPECT_EQ(unittest::SPARSE_E, unittest::TestSparseEnum_MIN); EXPECT_EQ(unittest::SPARSE_C, unittest::TestSparseEnum_MAX); + EXPECT_EQ(12589235, unittest::TestSparseEnum_ARRAYSIZE); - // Make sure we can use _MIN and _MAX as switch cases. - switch(unittest::SPARSE_A) { + // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE. + void* nullptr = 0; // NULL may be integer-type, not pointer-type. + EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_MIN); + EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_MAX); + EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE); + + EXPECT_NE(nullptr, &unittest::ForeignEnum_MIN); + EXPECT_NE(nullptr, &unittest::ForeignEnum_MAX); + EXPECT_NE(nullptr, &unittest::ForeignEnum_ARRAYSIZE); + + // Make sure we can use _MIN, _MAX and _ARRAYSIZE as switch cases. + switch (unittest::SPARSE_A) { case unittest::TestSparseEnum_MIN: case unittest::TestSparseEnum_MAX: + case unittest::TestSparseEnum_ARRAYSIZE: break; default: break; @@ -1136,6 +1164,43 @@ TEST_F(GeneratedServiceTest, NotImplemented) { EXPECT_TRUE(controller.called_); } +} // namespace cpp_unittest +} // namespace cpp +} // namespace compiler + +namespace no_generic_services_test { + // Verify that no class called "TestService" was defined in + // unittest_no_generic_services.pb.h by defining a different type by the same + // name. If such a service was generated, this will not compile. + struct TestService { + int i; + }; +} + +namespace compiler { +namespace cpp { +namespace cpp_unittest { + +TEST_F(GeneratedServiceTest, NoGenericServices) { + // Verify that non-services in unittest_no_generic_services.proto were + // generated. + no_generic_services_test::TestMessage message; + message.set_a(1); + message.SetExtension(no_generic_services_test::test_extension, 123); + no_generic_services_test::TestEnum e = no_generic_services_test::FOO; + EXPECT_EQ(e, 1); + + // Verify that a ServiceDescriptor is generated for the service even if the + // class itself is not. + const FileDescriptor* file = + no_generic_services_test::TestMessage::descriptor()->file(); + + ASSERT_EQ(1, file->service_count()); + EXPECT_EQ("TestService", file->service(0)->name()); + ASSERT_EQ(1, file->service(0)->method_count()); + EXPECT_EQ("Foo", file->service(0)->method(0)->name()); +} + #endif // !PROTOBUF_TEST_NO_DESCRIPTORS // =================================================================== diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index 8a07dfc..7689ce9 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -59,6 +59,7 @@ namespace compiler { #ifndef F_OK #define F_OK 00 // not defined by MSVC for whatever reason #endif +#include <ctype.h> #endif // Returns true if the text looks like a Windows-style absolute path, starting diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index 8ade50c..85e39f5 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -223,6 +223,11 @@ void EnumGenerator::Generate(io::Printer* printer) { "file", ClassName(descriptor_->file())); } + printer->Print( + "\n" + "// @@protoc_insertion_point(enum_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + printer->Outdent(); printer->Print("}\n\n"); } diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index dc36e06..af6b1cd 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -62,7 +62,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor, (*variables)["default"] = DefaultValue(descriptor); (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); (*variables)["tag_size"] = SimpleItoa( - internal::WireFormat::TagSize(descriptor->number(), descriptor->type())); + internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor))); } } // namespace @@ -81,7 +81,7 @@ void EnumFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "private boolean has$capitalized_name$;\n" - "private $type$ $name$_ = $default$;\n" + "private $type$ $name$_;\n" "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" "public $type$ get$capitalized_name$() { return $name$_; }\n"); } @@ -111,6 +111,11 @@ GenerateBuilderMembers(io::Printer* printer) const { } void EnumFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void EnumFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" @@ -241,6 +246,11 @@ GenerateBuilderMembers(io::Printer* printer) const { } void RepeatedEnumFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + // Initialized inline. +} + +void RepeatedEnumFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (!other.$name$_.isEmpty()) {\n" @@ -262,15 +272,6 @@ GenerateBuildingCode(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateParsingCode(io::Printer* printer) const { - // If packed, set up the while loop - if (descriptor_->options().packed()) { - printer->Print(variables_, - "int length = input.readRawVarint32();\n" - "int oldLimit = input.pushLimit(length);\n" - "while(input.getBytesUntilLimit() > 0) {\n"); - printer->Indent(); - } - // Read and store the enum printer->Print(variables_, "int rawValue = input.readEnum();\n" @@ -287,13 +288,24 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, " add$capitalized_name$(value);\n" "}\n"); +} - if (descriptor_->options().packed()) { - printer->Outdent(); - printer->Print(variables_, - "}\n" - "input.popLimit(oldLimit);\n"); - } +void RepeatedEnumFieldGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + // Wrap GenerateParsingCode's contents with a while loop. + + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int oldLimit = input.pushLimit(length);\n" + "while(input.getBytesUntilLimit() > 0) {\n"); + printer->Indent(); + + GenerateParsingCode(printer); + + printer->Outdent(); + printer->Print(variables_, + "}\n" + "input.popLimit(oldLimit);\n"); } void RepeatedEnumFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h index 63f6815..c54a0fa 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.h +++ b/src/google/protobuf/compiler/java/java_enum_field.h @@ -52,6 +52,7 @@ class EnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; @@ -75,9 +76,11 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc index 4403220..903b0a9 100644 --- a/src/google/protobuf/compiler/java/java_extension.cc +++ b/src/google/protobuf/compiler/java/java_extension.cc @@ -112,16 +112,20 @@ void ExtensionGenerator::Generate(io::Printer* printer) { "public static final int $constant_name$ = $number$;\n"); if (descriptor_->is_repeated()) { printer->Print(vars, - "public static\n" + "public static final\n" " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n" " $containing_type$,\n" - " java.util.List<$type$>> $name$;\n"); + " java.util.List<$type$>> $name$ =\n" + " com.google.protobuf.GeneratedMessage$lite$\n" + " .newGeneratedExtension();\n"); } else { printer->Print(vars, - "public static\n" + "public static final\n" " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n" " $containing_type$,\n" - " $type$> $name$;\n"); + " $type$> $name$ =\n" + " com.google.protobuf.GeneratedMessage$lite$\n" + " .newGeneratedExtension();\n"); } } @@ -133,7 +137,7 @@ void ExtensionGenerator::GenerateInitializationCode(io::Printer* printer) { vars["extendee"] = ClassName(descriptor_->containing_type()); vars["default"] = descriptor_->is_repeated() ? "" : DefaultValue(descriptor_); vars["number"] = SimpleItoa(descriptor_->number()); - vars["type_constant"] = TypeName(descriptor_->type()); + vars["type_constant"] = TypeName(GetType(descriptor_)); vars["packed"] = descriptor_->options().packed() ? "true" : "false"; vars["enum_map"] = "null"; vars["prototype"] = "null"; @@ -157,43 +161,29 @@ void ExtensionGenerator::GenerateInitializationCode(io::Printer* printer) { } if (HasDescriptorMethods(descriptor_->file())) { - if (descriptor_->is_repeated()) { - printer->Print(vars, - "$scope$.$name$ =\n" - " com.google.protobuf.GeneratedMessage\n" - " .newRepeatedGeneratedExtension(\n" - " $scope$.getDescriptor().getExtensions().get($index$),\n" - " $type$.class);\n"); - } else { - printer->Print(vars, - "$scope$.$name$ =\n" - " com.google.protobuf.GeneratedMessage.newGeneratedExtension(\n" - " $scope$.getDescriptor().getExtensions().get($index$),\n" - " $type$.class);\n"); - } + printer->Print(vars, + "$scope$.$name$.internalInit(\n" + " $scope$.getDescriptor().getExtensions().get($index$),\n" + " $type$.class);\n"); } else { if (descriptor_->is_repeated()) { printer->Print(vars, - "$scope$.$name$ =\n" - " com.google.protobuf.GeneratedMessageLite\n" - " .newRepeatedGeneratedExtension(\n" - " $extendee$.getDefaultInstance(),\n" - " $prototype$,\n" - " $enum_map$,\n" - " $number$,\n" - " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" - " $packed$);\n"); + "$scope$.$name$.internalInitRepeated(\n" + " $extendee$.getDefaultInstance(),\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" + " $packed$);\n"); } else { printer->Print(vars, - "$scope$.$name$ =\n" - " com.google.protobuf.GeneratedMessageLite\n" - " .newGeneratedExtension(\n" - " $extendee$.getDefaultInstance(),\n" - " $default$,\n" - " $prototype$,\n" - " $enum_map$,\n" - " $number$,\n" - " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n"); + "$scope$.$name$.internalInitSingular(\n" + " $extendee$.getDefaultInstance(),\n" + " $default$,\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n"); } } } @@ -208,5 +198,4 @@ void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) { } // namespace java } // namespace compiler } // namespace protobuf - } // namespace google diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc index f9d34ad..978c8f3 100644 --- a/src/google/protobuf/compiler/java/java_field.cc +++ b/src/google/protobuf/compiler/java/java_field.cc @@ -46,6 +46,16 @@ namespace java { FieldGenerator::~FieldGenerator() {} +void FieldGenerator::GenerateParsingCodeFromPacked(io::Printer* printer) const { + // Reaching here indicates a bug. Cases are: + // - This FieldGenerator should support packing, but this method should be + // overridden. + // - This FieldGenerator doesn't support packing, and this method should + // never have been called. + GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() " + << "called on field generator that does not support packing."; +} + FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) : descriptor_(descriptor), field_generators_( diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h index cab463c..f5bef7a 100644 --- a/src/google/protobuf/compiler/java/java_field.h +++ b/src/google/protobuf/compiler/java/java_field.h @@ -57,9 +57,11 @@ class FieldGenerator { virtual void GenerateMembers(io::Printer* printer) const = 0; virtual void GenerateBuilderMembers(io::Printer* printer) const = 0; + virtual void GenerateInitializationCode(io::Printer* printer) const = 0; virtual void GenerateMergingCode(io::Printer* printer) const = 0; virtual void GenerateBuildingCode(io::Printer* printer) const = 0; virtual void GenerateParsingCode(io::Printer* printer) const = 0; + virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const; virtual void GenerateSerializationCode(io::Printer* printer) const = 0; virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 2aedde5..7ea127c 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -64,7 +64,7 @@ bool UsesExtensions(const Message& message) { for (int i = 0; i < fields.size(); i++) { if (fields[i]->is_extension()) return true; - if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { if (fields[i]->is_repeated()) { int size = reflection->FieldSize(message, fields[i]); for (int j = 0; j < size; j++) { @@ -82,6 +82,7 @@ bool UsesExtensions(const Message& message) { return false; } + } // namespace FileGenerator::FileGenerator(const FileDescriptor* file) @@ -134,7 +135,9 @@ void FileGenerator::Generate(io::Printer* printer) { // fully-qualified names in the generated source. printer->Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n"); + "// source: $filename$\n" + "\n", + "filename", file_->name()); if (!java_package_.empty()) { printer->Print( "package $package$;\n" @@ -178,8 +181,10 @@ void FileGenerator::Generate(io::Printer* printer) { for (int i = 0; i < file_->message_type_count(); i++) { MessageGenerator(file_->message_type(i)).Generate(printer); } - for (int i = 0; i < file_->service_count(); i++) { - ServiceGenerator(file_->service(i)).Generate(printer); + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + ServiceGenerator(file_->service(i)).Generate(printer); + } } } @@ -228,6 +233,10 @@ void FileGenerator::Generate(io::Printer* printer) { "\n" "public static void internalForceInit() {}\n"); + printer->Print( + "\n" + "// @@protoc_insertion_point(outer_class_scope)\n"); + printer->Outdent(); printer->Print("}\n"); } @@ -245,6 +254,7 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) { // embedded raw, which is what we want. FileDescriptorProto file_proto; file_->CopyTo(&file_proto); + string file_data; file_proto.SerializeToString(&file_data); @@ -343,9 +353,11 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) { " new com.google.protobuf.Descriptors.FileDescriptor[] {\n"); for (int i = 0; i < file_->dependency_count(); i++) { - printer->Print( - " $dependency$.getDescriptor(),\n", - "dependency", ClassName(file_->dependency(i))); + if (ShouldIncludeDependency(file_->dependency(i))) { + printer->Print( + " $dependency$.getDescriptor(),\n", + "dependency", ClassName(file_->dependency(i))); + } } printer->Print( @@ -396,14 +408,20 @@ void FileGenerator::GenerateSiblings(const string& package_dir, file_->message_type(i), output_directory, file_list); } - for (int i = 0; i < file_->service_count(); i++) { - GenerateSibling<ServiceGenerator>(package_dir, java_package_, - file_->service(i), - output_directory, file_list); + if (HasGenericServices(file_)) { + for (int i = 0; i < file_->service_count(); i++) { + GenerateSibling<ServiceGenerator>(package_dir, java_package_, + file_->service(i), + output_directory, file_list); + } } } } +bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor) { + return true; +} + } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h index cb82cea..9e35d33 100644 --- a/src/google/protobuf/compiler/java/java_file.h +++ b/src/google/protobuf/compiler/java/java_file.h @@ -77,6 +77,11 @@ class FileGenerator { const string& classname() { return classname_; } private: + // Returns whether the dependency should be included in the output file. + // Always returns true for opensource, but used internally at Google to help + // improve compatibility with version 1 of protocol buffers. + bool ShouldIncludeDependency(const FileDescriptor* descriptor); + const FileDescriptor* file_; string java_package_; string classname_; diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc index 8ed3aff..745b55a 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -45,6 +45,7 @@ namespace protobuf { namespace compiler { namespace java { + JavaGenerator::JavaGenerator() {} JavaGenerator::~JavaGenerator() {} diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index dc6748e..7ed0c3c 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -32,6 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <limits> #include <vector> #include <google/protobuf/compiler/java/java_helpers.h> @@ -57,7 +58,7 @@ const string& FieldName(const FieldDescriptor* field) { // Groups are hacky: The name of the field is just the lower-cased name // of the group type. In Java, though, we would like to retain the original // capitalization of the type name. - if (field->type() == FieldDescriptor::TYPE_GROUP) { + if (GetType(field) == FieldDescriptor::TYPE_GROUP) { return field->message_type()->name(); } else { return field->name(); @@ -178,8 +179,12 @@ string FieldConstantName(const FieldDescriptor *field) { return name; } -JavaType GetJavaType(FieldDescriptor::Type field_type) { - switch (field_type) { +FieldDescriptor::Type GetType(const FieldDescriptor* field) { + return field->type(); +} + +JavaType GetJavaType(const FieldDescriptor* field) { + switch (GetType(field)) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_UINT32: case FieldDescriptor::TYPE_SINT32: @@ -254,7 +259,7 @@ bool AllAscii(const string& text) { } string DefaultValue(const FieldDescriptor* field) { - // Switch on cpp_type since we need to know which default_value_* method + // Switch on CppType since we need to know which default_value_* method // of FieldDescriptor to call. switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: @@ -267,14 +272,34 @@ string DefaultValue(const FieldDescriptor* field) { case FieldDescriptor::CPPTYPE_UINT64: return SimpleItoa(static_cast<int64>(field->default_value_uint64())) + "L"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field->default_value_double()) + "D"; - case FieldDescriptor::CPPTYPE_FLOAT: - return SimpleFtoa(field->default_value_float()) + "F"; + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value = field->default_value_double(); + if (value == numeric_limits<double>::infinity()) { + return "Double.POSITIVE_INFINITY"; + } else if (value == -numeric_limits<double>::infinity()) { + return "Double.NEGATIVE_INFINITY"; + } else if (value != value) { + return "Double.NaN"; + } else { + return SimpleDtoa(value) + "D"; + } + } + case FieldDescriptor::CPPTYPE_FLOAT: { + float value = field->default_value_float(); + if (value == numeric_limits<float>::infinity()) { + return "Float.POSITIVE_INFINITY"; + } else if (value == -numeric_limits<float>::infinity()) { + return "Float.NEGATIVE_INFINITY"; + } else if (value != value) { + return "Float.NaN"; + } else { + return SimpleFtoa(value) + "F"; + } + } case FieldDescriptor::CPPTYPE_BOOL: return field->default_value_bool() ? "true" : "false"; case FieldDescriptor::CPPTYPE_STRING: - if (field->type() == FieldDescriptor::TYPE_BYTES) { + if (GetType(field) == FieldDescriptor::TYPE_BYTES) { if (field->has_default_value()) { // See comments in Internal.java for gory details. return strings::Substitute( diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index f1b643c..3c8974c 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -93,6 +93,11 @@ string ClassName(const FileDescriptor* descriptor); // number constant. string FieldConstantName(const FieldDescriptor *field); +// Returns the type of the FieldDescriptor. +// This does nothing interesting for the open source release, but is used for +// hacks that improve compatability with version 1 protocol buffers at Google. +FieldDescriptor::Type GetType(const FieldDescriptor* field); + enum JavaType { JAVATYPE_INT, JAVATYPE_LONG, @@ -105,11 +110,7 @@ enum JavaType { JAVATYPE_MESSAGE }; -JavaType GetJavaType(FieldDescriptor::Type field_type); - -inline JavaType GetJavaType(const FieldDescriptor* field) { - return GetJavaType(field->type()); -} +JavaType GetJavaType(const FieldDescriptor* field); // Get the fully-qualified class name for a boxed primitive type, e.g. // "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message @@ -145,6 +146,13 @@ inline bool HasDescriptorMethods(const FileDescriptor* descriptor) { FileOptions::LITE_RUNTIME; } +// Should we generate generic services for this file? +inline bool HasGenericServices(const FileDescriptor *file) { + return file->service_count() > 0 && + file->options().optimize_for() != FileOptions::LITE_RUNTIME && + file->options().java_generic_services(); +} + } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 332a118..a326057 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -127,7 +127,7 @@ static bool HasRequiredFields( if (field->is_required()) { return true; } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (GetJavaType(field) == JAVATYPE_MESSAGE) { if (HasRequiredFields(field->message_type(), already_seen)) { return true; } @@ -292,9 +292,14 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Indent(); printer->Print( "// Use $classname$.newBuilder() to construct.\n" - "private $classname$() {}\n" + "private $classname$() {\n" + " initFields();\n" + "}\n" + // Used when constructing the default instance, which cannot be initialized + // immediately because it may cyclically refer to other default instances. + "private $classname$(boolean noInit) {}\n" "\n" - "private static final $classname$ defaultInstance = new $classname$();\n" + "private static final $classname$ defaultInstance;\n" "public static $classname$ getDefaultInstance() {\n" " return defaultInstance;\n" "}\n" @@ -344,6 +349,17 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print("\n"); } + // Called by the constructor, except in the case of the default instance, + // in which case this is called by static init code later on. + printer->Print("private void initFields() {\n"); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateInitializationCode(printer); + } + printer->Outdent(); + printer->Print("}\n"); + if (HasGeneratedMethods(descriptor_)) { GenerateIsInitialized(printer); GenerateMessageSerializationMethods(printer); @@ -352,25 +368,23 @@ void MessageGenerator::Generate(io::Printer* printer) { GenerateParseFromMethods(printer); GenerateBuilder(printer); - if (HasDescriptorMethods(descriptor_)) { - // Force the static initialization code for the file to run, since it may - // initialize static variables declared in this class. - printer->Print( - "\n" - "static {\n" - " $file$.getDescriptor();\n" - "}\n", - "file", ClassName(descriptor_->file())); - } - // Force initialization of outer class. Otherwise, nested extensions may - // not be initialized. + // not be initialized. Also carefully initialize the default instance in + // such a way that it doesn't conflict with other initialization. printer->Print( "\n" "static {\n" + " defaultInstance = new $classname$(true);\n" " $file$.internalForceInit();\n" + " defaultInstance.initFields();\n" "}\n", - "file", ClassName(descriptor_->file())); + "file", ClassName(descriptor_->file()), + "classname", descriptor_->name()); + + printer->Print( + "\n" + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); printer->Outdent(); printer->Print("}\n\n"); @@ -394,6 +408,14 @@ GenerateMessageSerializationMethods(io::Printer* printer) { "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" " throws java.io.IOException {\n"); printer->Indent(); + // writeTo(CodedOutputStream output) might be invoked without + // getSerializedSize() ever being called, but we need the memoized + // sizes in case this message has packed fields. Rather than emit checks for + // each packed field, just call getSerializedSize() up front for all messages. + // In most cases, getSerializedSize() will have already been called anyway by + // one of the wrapper writeTo() methods, making this call cheap. + printer->Print( + "getSerializedSize();\n"); if (descriptor_->extension_range_count() > 0) { if (descriptor_->options().message_set_wire_format()) { @@ -521,14 +543,23 @@ GenerateParseFromMethods(io::Printer* printer) { "}\n" "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n" " throws java.io.IOException {\n" - " return newBuilder().mergeDelimitedFrom(input).buildParsed();\n" + " Builder builder = newBuilder();\n" + " if (builder.mergeDelimitedFrom(input)) {\n" + " return builder.buildParsed();\n" + " } else {\n" + " return null;\n" + " }\n" "}\n" "public static $classname$ parseDelimitedFrom(\n" " java.io.InputStream input,\n" " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" " throws java.io.IOException {\n" - " return newBuilder().mergeDelimitedFrom(input, extensionRegistry)\n" - " .buildParsed();\n" + " Builder builder = newBuilder();\n" + " if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n" + " return builder.buildParsed();\n" + " } else {\n" + " return null;\n" + " }\n" "}\n" "public static $classname$ parseFrom(\n" " com.google.protobuf.CodedInputStream input)\n" @@ -614,6 +645,11 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) { .GenerateBuilderMembers(printer); } + printer->Print( + "\n" + "// @@protoc_insertion_point(builder_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + printer->Outdent(); printer->Print("}\n"); } @@ -819,7 +855,7 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = sorted_fields[i]; uint32 tag = WireFormatLite::MakeTag(field->number(), - WireFormat::WireTypeForField(field)); + WireFormat::WireTypeForFieldType(field->type())); printer->Print( "case $tag$: {\n", @@ -832,6 +868,24 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { printer->Print( " break;\n" "}\n"); + + if (field->is_packable()) { + // To make packed = true wire compatible, we generate parsing code from a + // packed version of this field regardless of field->options().packed(). + uint32 packed_tag = WireFormatLite::MakeTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + printer->Print( + "case $tag$: {\n", + "tag", SimpleItoa(packed_tag)); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCodeFromPacked(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + } } printer->Outdent(); @@ -867,7 +921,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { // Now check that all embedded messages are initialized. for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + if (GetJavaType(field) == JAVATYPE_MESSAGE && HasRequiredFields(field->message_type())) { switch (field->label()) { case FieldDescriptor::LABEL_REQUIRED: diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index bbddddd..71edc02 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -59,7 +59,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["number"] = SimpleItoa(descriptor->number()); (*variables)["type"] = ClassName(descriptor->message_type()); (*variables)["group_or_message"] = - (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? + (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; } @@ -79,7 +79,7 @@ void MessageFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "private boolean has$capitalized_name$;\n" - "private $type$ $name$_ = $type$.getDefaultInstance();\n" + "private $type$ $name$_;\n" "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" "public $type$ get$capitalized_name$() { return $name$_; }\n"); } @@ -125,6 +125,11 @@ GenerateBuilderMembers(io::Printer* printer) const { } void MessageFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n"); +} + +void MessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" @@ -145,7 +150,7 @@ GenerateParsingCode(io::Printer* printer) const { " subBuilder.mergeFrom(get$capitalized_name$());\n" "}\n"); - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { printer->Print(variables_, "input.readGroup($number$, subBuilder, extensionRegistry);\n"); } else { @@ -262,6 +267,11 @@ GenerateBuilderMembers(io::Printer* printer) const { } void RepeatedMessageFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + // Initialized inline. +} + +void RepeatedMessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (!other.$name$_.isEmpty()) {\n" @@ -286,7 +296,7 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "$type$.Builder subBuilder = $type$.newBuilder();\n"); - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { printer->Print(variables_, "input.readGroup($number$, subBuilder, extensionRegistry);\n"); } else { diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h index 90a9097..66bdd88 100644 --- a/src/google/protobuf/compiler/java/java_message_field.h +++ b/src/google/protobuf/compiler/java/java_message_field.h @@ -52,6 +52,7 @@ class MessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; @@ -75,6 +76,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/google/protobuf/compiler/java/java_plugin_unittest.cc new file mode 100644 index 0000000..cfe0188 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_plugin_unittest.cc @@ -0,0 +1,121 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// TODO(kenton): Share code with the versions of this test in other languages? +// It seemed like parameterizing it would add more complexity than it is +// worth. + +#include <google/protobuf/compiler/java/java_generator.h> +#include <google/protobuf/compiler/command_line_interface.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/printer.h> + +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> +#include <google/protobuf/testing/file.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +namespace { + +class TestGenerator : public CodeGenerator { + public: + TestGenerator() {} + ~TestGenerator() {} + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const { + TryInsert("Test.java", "outer_class_scope", output_directory); + TryInsert("Test.java", "class_scope:foo.Bar", output_directory); + TryInsert("Test.java", "class_scope:foo.Bar.Baz", output_directory); + TryInsert("Test.java", "builder_scope:foo.Bar", output_directory); + TryInsert("Test.java", "builder_scope:foo.Bar.Baz", output_directory); + TryInsert("Test.java", "enum_scope:foo.Qux", output_directory); + return true; + } + + void TryInsert(const string& filename, const string& insertion_point, + OutputDirectory* output_directory) const { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->OpenForInsert(filename, insertion_point)); + io::Printer printer(output.get(), '$'); + printer.Print("// inserted $name$\n", "name", insertion_point); + } +}; + +// This test verifies that all the expected insertion points exist. It does +// not verify that they are correctly-placed; that would require actually +// compiling the output which is a bit more than I care to do for this test. +TEST(JavaPluginTest, PluginTest) { + File::WriteStringToFileOrDie( + "syntax = \"proto2\";\n" + "package foo;\n" + "option java_package = \"\";\n" + "option java_outer_classname = \"Test\";\n" + "message Bar {\n" + " message Baz {}\n" + "}\n" + "enum Qux { BLAH = 1; }\n", + TestTempDir() + "/test.proto"); + + google::protobuf::compiler::CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + JavaGenerator java_generator; + TestGenerator test_generator; + cli.RegisterGenerator("--java_out", &java_generator, ""); + cli.RegisterGenerator("--test_out", &test_generator, ""); + + string proto_path = "-I" + TestTempDir(); + string java_out = "--java_out=" + TestTempDir(); + string test_out = "--test_out=" + TestTempDir(); + + const char* argv[] = { + "protoc", + proto_path.c_str(), + java_out.c_str(), + test_out.c_str(), + "test.proto" + }; + + EXPECT_EQ(0, cli.Run(5, argv)); +} + +} // namespace +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index 327c205..f6179bf 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -93,7 +93,7 @@ bool IsReferenceType(JavaType type) { } const char* GetCapitalizedType(const FieldDescriptor* field) { - switch (field->type()) { + switch (GetType(field)) { case FieldDescriptor::TYPE_INT32 : return "Int32" ; case FieldDescriptor::TYPE_UINT32 : return "UInt32" ; case FieldDescriptor::TYPE_SINT32 : return "SInt32" ; @@ -166,7 +166,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); (*variables)["tag_size"] = SimpleItoa( - WireFormat::TagSize(descriptor->number(), descriptor->type())); + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); if (IsReferenceType(GetJavaType(descriptor))) { (*variables)["null_check"] = " if (value == null) {\n" @@ -175,7 +175,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } else { (*variables)["null_check"] = ""; } - int fixed_size = FixedSize(descriptor->type()); + int fixed_size = FixedSize(GetType(descriptor)); if (fixed_size != -1) { (*variables)["fixed_size"] = SimpleItoa(fixed_size); } @@ -218,7 +218,8 @@ GenerateBuilderMembers(io::Printer* printer) const { "}\n" "public Builder clear$capitalized_name$() {\n" " result.has$capitalized_name$ = false;\n"); - if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + JavaType type = GetJavaType(descriptor_); + if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { // The default value is not a simple literal so we want to avoid executing // it multiple times. Instead, get the default out of the default instance. printer->Print(variables_, @@ -233,6 +234,11 @@ GenerateBuilderMembers(io::Printer* printer) const { } void PrimitiveFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + // Initialized inline. +} + +void PrimitiveFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" @@ -298,7 +304,7 @@ GenerateMembers(io::Printer* printer) const { if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->containing_type())) { printer->Print(variables_, - "private int $name$MemoizedSerializedSize;\n"); + "private int $name$MemoizedSerializedSize = -1;\n"); } } @@ -346,6 +352,11 @@ GenerateBuilderMembers(io::Printer* printer) const { } void RepeatedPrimitiveFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + // Initialized inline. +} + +void RepeatedPrimitiveFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (!other.$name$_.isEmpty()) {\n" @@ -367,18 +378,19 @@ GenerateBuildingCode(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateParsingCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { - printer->Print(variables_, - "int length = input.readRawVarint32();\n" - "int limit = input.pushLimit(length);\n" - "while (input.getBytesUntilLimit() > 0) {\n" - " add$capitalized_name$(input.read$capitalized_type$());\n" - "}\n" - "input.popLimit(limit);\n"); - } else { - printer->Print(variables_, - "add$capitalized_name$(input.read$capitalized_type$());\n"); - } + printer->Print(variables_, + "add$capitalized_name$(input.read$capitalized_type$());\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " add$capitalized_name$(input.read$capitalized_type$());\n" + "}\n" + "input.popLimit(limit);\n"); } void RepeatedPrimitiveFieldGenerator:: @@ -407,7 +419,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { " int dataSize = 0;\n"); printer->Indent(); - if (FixedSize(descriptor_->type()) == -1) { + if (FixedSize(GetType(descriptor_)) == -1) { printer->Print(variables_, "for ($type$ element : get$capitalized_name$List()) {\n" " dataSize += com.google.protobuf.CodedOutputStream\n" diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h index f9da0a6..4e482a0 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.h +++ b/src/google/protobuf/compiler/java/java_primitive_field.h @@ -52,6 +52,7 @@ class PrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; @@ -75,9 +76,11 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum.cc b/src/google/protobuf/compiler/javamicro/javamicro_enum.cc deleted file mode 100644 index d74a149..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_enum.cc +++ /dev/null @@ -1,96 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/javamicro/javamicro_params.h> -#include <google/protobuf/compiler/javamicro/javamicro_enum.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Params& params) - : params_(params), descriptor_(descriptor) { - for (int i = 0; i < descriptor_->value_count(); i++) { - const EnumValueDescriptor* value = descriptor_->value(i); - const EnumValueDescriptor* canonical_value = - descriptor_->FindValueByNumber(value->number()); - - if (value == canonical_value) { - canonical_values_.push_back(value); - } else { - Alias alias; - alias.value = value; - alias.canonical_value = canonical_value; - aliases_.push_back(alias); - } - } -} - -EnumGenerator::~EnumGenerator() {} - -void EnumGenerator::Generate(io::Printer* printer) { - printer->Print("// enum $classname$\n", "classname", descriptor_->name()); - for (int i = 0; i < canonical_values_.size(); i++) { - map<string, string> vars; - vars["name"] = canonical_values_[i]->name(); - vars["canonical_value"] = SimpleItoa(canonical_values_[i]->number()); - printer->Print(vars, - "public static final int $name$ = $canonical_value$;\n"); - } - - // ----------------------------------------------------------------- - - for (int i = 0; i < aliases_.size(); i++) { - map<string, string> vars; - vars["name"] = aliases_[i].value->name(); - vars["canonical_name"] = aliases_[i].canonical_value->name(); - printer->Print(vars, - "public static final int $name$ = $canonical_name$;\n"); - } - - printer->Print("\n"); -} - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum.h b/src/google/protobuf/compiler/javamicro/javamicro_enum.h deleted file mode 100644 index 9cf226f..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_enum.h +++ /dev/null @@ -1,87 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ - -#include <string> -#include <vector> - -#include <google/protobuf/compiler/javamicro/javamicro_params.h> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace javamicro { - -class EnumGenerator { - public: - explicit EnumGenerator(const EnumDescriptor* descriptor, const Params& params); - ~EnumGenerator(); - - void Generate(io::Printer* printer); - - private: - const Params& params_; - const EnumDescriptor* descriptor_; - - // The proto language allows multiple enum constants to have the same numeric - // value. Java, however, does not allow multiple enum constants to be - // considered equivalent. We treat the first defined constant for any - // given numeric value as "canonical" and the rest as aliases of that - // canonical value. - vector<const EnumValueDescriptor*> canonical_values_; - - struct Alias { - const EnumValueDescriptor* value; - const EnumValueDescriptor* canonical_value; - }; - vector<Alias> aliases_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); -}; - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc deleted file mode 100644 index 0ff49a3..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc +++ /dev/null @@ -1,333 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/javamicro/javamicro_enum_field.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -namespace { - -// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of -// repeat code between this and the other field types. -void SetEnumVariables(const Params& params, - const FieldDescriptor* descriptor, map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = "int"; - (*variables)["default"] = DefaultValue(params, descriptor); - (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); - (*variables)["tag_size"] = SimpleItoa( - internal::WireFormat::TagSize(descriptor->number(), descriptor->type())); - (*variables)["message_name"] = descriptor->containing_type()->name(); -} - -} // namespace - -// =================================================================== - -EnumFieldGenerator:: -EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params) - : FieldGenerator(params), descriptor_(descriptor) { - SetEnumVariables(params, descriptor, &variables_); -} - -EnumFieldGenerator::~EnumFieldGenerator() {} - -void EnumFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private boolean has$capitalized_name$;\n" - "private int $name$_ = $default$;\n" - "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" - "public int get$capitalized_name$() { return $name$_; }\n" - "public $message_name$ set$capitalized_name$(int value) {\n" - " has$capitalized_name$ = true;\n" - " $name$_ = value;\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " has$capitalized_name$ = false;\n" - " $name$_ = $default$;\n" - " return this;\n" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "what is other??" - "if (other.has$capitalized_name$()) {\n" - " set$capitalized_name$(other.get$capitalized_name$());\n" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - " set$capitalized_name$(input.readInt32());\n"); -} - -void EnumFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.writeInt32($number$, get$capitalized_name$());\n" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .computeInt32Size($number$, get$capitalized_name$());\n" - "}\n"); -} - -string EnumFieldGenerator::GetBoxedType() const { - return ClassName(params_, descriptor_->enum_type()); -} - -// =================================================================== - -RepeatedEnumFieldGenerator:: -RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params) - : FieldGenerator(params), descriptor_(descriptor) { - SetEnumVariables(params, descriptor, &variables_); - if (descriptor_->options().packed()) { - GOOGLE_LOG(FATAL) << "MicroRuntime does not support packed"; - } -} - -RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} - -void RepeatedEnumFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - if (params_.java_use_vector()) { - printer->Print(variables_, - "private java.util.Vector $name$_ = new java.util.Vector();\n" - "public java.util.Vector get$capitalized_name$List() {\n" - " return $name$_;\n" - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public int get$capitalized_name$(int index) {\n" - " return ((Integer)$name$_.elementAt(index)).intValue();\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, int value) {\n" - " $name$_.setElementAt(new Integer(value), index);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$(int value) {\n" - " $name$_.addElement(new Integer(value));\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_.removeAllElements();\n" - " return this;\n" - "}\n"); - } else { - printer->Print(variables_, - "private java.util.List<Integer> $name$_ =\n" - " java.util.Collections.emptyList();\n" - "public java.util.List<Integer> get$capitalized_name$List() {\n" - " return $name$_;\n" // note: unmodifiable list - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public int get$capitalized_name$(int index) {\n" - " return $name$_.get(index);\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, int value) {\n" - " $name$_.set(index, value);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$(int value) {\n" - " if ($name$_.isEmpty()) {\n" - " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n" - " }\n" - " $name$_.add(value);\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); - } - if (descriptor_->options().packed()) { - printer->Print(variables_, - "private int $name$MemoizedSerializedSize;\n"); - } -} - -void RepeatedEnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - if (params_.java_use_vector()) { - printer->Print(variables_, - "if (other.$name$_.size() != 0) {\n" - " for (int i = 0; i < other.$name$_.size(); i++)) {\n" - " result.$name$_.addElement(other.$name$_.elementAt(i));\n" - " }\n" - "}\n"); - } else { - printer->Print(variables_, - "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<java.lang.Integer>();\n" - " }\n" - " result.$name$_.addAll(other.$name$_);\n" - "}\n"); - } -} - -void RepeatedEnumFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - // If packed, set up the while loop - if (descriptor_->options().packed()) { - printer->Print(variables_, - "int length = input.readRawVarint32();\n" - "int oldLimit = input.pushLimit(length);\n" - "while(input.getBytesUntilLimit() > 0) {\n"); - printer->Indent(); - } - - // Read and store the enum - printer->Print(variables_, - " add$capitalized_name$(input.readInt32());\n"); - - if (descriptor_->options().packed()) { - printer->Outdent(); - printer->Print(variables_, - "}\n" - "input.popLimit(oldLimit);\n"); - } -} - -void RepeatedEnumFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { - printer->Print(variables_, - "if (get$capitalized_name$List().size() > 0) {\n" - " output.writeRawVarint32($tag$);\n" - " output.writeRawVarint32($name$MemoizedSerializedSize);\n" - "}\n"); - if (params_.java_use_vector()) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " output.writeRawVarint32(get$capitalized_name$(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.writeRawVarint32(element.getNumber());\n" - "}\n"); - } - } else { - if (params_.java_use_vector()) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " output.writeInt32($number$, (int)get$capitalized_name$(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "for (java.lang.Integer element : get$capitalized_name$List()) {\n" - " output.writeInt32($number$, element);\n" - "}\n"); - } - } -} - -void RepeatedEnumFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "{\n" - " int dataSize = 0;\n"); - printer->Indent(); - if (params_.java_use_vector()) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .computeInt32SizeNoTag(get$capitalized_name$(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "for (java.lang.Integer element : get$capitalized_name$List()) {\n" - " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .computeInt32SizeNoTag(element);\n" - "}\n"); - } - printer->Print( - "size += dataSize;\n"); - if (descriptor_->options().packed()) { - printer->Print(variables_, - "if (get$capitalized_name$List().size() != 0) {" - " size += $tag_size$;\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .computeRawVarint32Size(dataSize);\n" - "}"); - } else { - printer->Print(variables_, - "size += $tag_size$ * get$capitalized_name$List().size();\n"); - } - - // cache the data size for packed fields. - if (descriptor_->options().packed()) { - printer->Print(variables_, - "$name$MemoizedSerializedSize = dataSize;\n"); - } - - printer->Outdent(); - printer->Print("}\n"); -} - -string RepeatedEnumFieldGenerator::GetBoxedType() const { - return ClassName(params_, descriptor_->enum_type()); -} - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h b/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h deleted file mode 100644 index ab671c1..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h +++ /dev/null @@ -1,94 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/javamicro/javamicro_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -class EnumFieldGenerator : public FieldGenerator { - public: - explicit EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params); - ~EnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); -}; - -class RepeatedEnumFieldGenerator : public FieldGenerator { - public: - explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params); - ~RepeatedEnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); -}; - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_field.cc deleted file mode 100644 index a2ea4f9..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_field.cc +++ /dev/null @@ -1,102 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/javamicro/javamicro_field.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/compiler/javamicro/javamicro_primitive_field.h> -#include <google/protobuf/compiler/javamicro/javamicro_enum_field.h> -#include <google/protobuf/compiler/javamicro/javamicro_message_field.h> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -FieldGenerator::~FieldGenerator() {} - -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, const Params ¶ms) - : descriptor_(descriptor), - field_generators_( - new scoped_ptr<FieldGenerator>[descriptor->field_count()]), - extension_generators_( - new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) { - - // Construct all the FieldGenerators. - for (int i = 0; i < descriptor->field_count(); i++) { - field_generators_[i].reset(MakeGenerator(descriptor->field(i), params)); - } - for (int i = 0; i < descriptor->extension_count(); i++) { - extension_generators_[i].reset(MakeGenerator(descriptor->extension(i), params)); - } -} - -FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, const Params ¶ms) { - if (field->is_repeated()) { - switch (GetJavaType(field)) { - case JAVATYPE_MESSAGE: - return new RepeatedMessageFieldGenerator(field, params); - case JAVATYPE_ENUM: - return new RepeatedEnumFieldGenerator(field, params); - default: - return new RepeatedPrimitiveFieldGenerator(field, params); - } - } else { - switch (GetJavaType(field)) { - case JAVATYPE_MESSAGE: - return new MessageFieldGenerator(field, params); - case JAVATYPE_ENUM: - return new EnumFieldGenerator(field, params); - default: - return new PrimitiveFieldGenerator(field, params); - } - } -} - -FieldGeneratorMap::~FieldGeneratorMap() {} - -const FieldGenerator& FieldGeneratorMap::get( - const FieldDescriptor* field) const { - GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); - return *field_generators_[field->index()]; -} - -const FieldGenerator& FieldGeneratorMap::get_extension(int index) const { - return *extension_generators_[index]; -} - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_file.cc b/src/google/protobuf/compiler/javamicro/javamicro_file.cc deleted file mode 100644 index 0985538..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_file.cc +++ /dev/null @@ -1,251 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/javamicro/javamicro_file.h> -#include <google/protobuf/compiler/javamicro/javamicro_enum.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/compiler/javamicro/javamicro_message.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -namespace { - -// Recursively searches the given message to see if it contains any extensions. -bool UsesExtensions(const Message& message) { - const Reflection* reflection = message.GetReflection(); - - // We conservatively assume that unknown fields are extensions. - if (reflection->GetUnknownFields(message).field_count() > 0) return true; - - vector<const FieldDescriptor*> fields; - reflection->ListFields(message, &fields); - - for (int i = 0; i < fields.size(); i++) { - if (fields[i]->is_extension()) return true; - - if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (fields[i]->is_repeated()) { - int size = reflection->FieldSize(message, fields[i]); - for (int j = 0; j < size; j++) { - const Message& sub_message = - reflection->GetRepeatedMessage(message, fields[i], j); - if (UsesExtensions(sub_message)) return true; - } - } else { - const Message& sub_message = reflection->GetMessage(message, fields[i]); - if (UsesExtensions(sub_message)) return true; - } - } - } - - return false; -} - -} // namespace - -FileGenerator::FileGenerator(const FileDescriptor* file, const Params& params) - : file_(file), - params_(params), - java_package_(FileJavaPackage(params, file)), - classname_(FileClassName(params, file)) {} - -FileGenerator::~FileGenerator() {} - -bool FileGenerator::Validate(string* error) { - // Check for extensions - FileDescriptorProto file_proto; - file_->CopyTo(&file_proto); - if (UsesExtensions(file_proto)) { - error->assign(file_->name()); - error->append( - ": Java MICRO_RUNTIME does not support extensions\""); - return false; - } - - // If there is no outer class name then there must be only - // message and no enums defined in the file scope. - if (!params_.has_java_outer_classname(file_->name())) { - if (file_->message_type_count() != 1) { - error->assign(file_->name()); - error->append( - ": Java MICRO_RUNTIME may only have 1 message if there is no 'option java_outer_classname'\""); - return false; - } - - if (file_->enum_type_count() != 0) { - error->assign(file_->name()); - error->append( - ": Java MICRO_RUNTIME must have an 'option java_outer_classname' if file scope enums are present\""); - return false; - } - } - - // Check that no class name matches the file's class name. This is a common - // problem that leads to Java compile errors that can be hard to understand. - // It's especially bad when using the java_multiple_files, since we would - // end up overwriting the outer class with one of the inner ones. - int found_fileName = 0; - for (int i = 0; i < file_->enum_type_count(); i++) { - if (file_->enum_type(i)->name() == classname_) { - found_fileName += 1; - } - } - for (int i = 0; i < file_->message_type_count(); i++) { - if (file_->message_type(i)->name() == classname_) { - found_fileName += 1; - } - } - if (file_->service_count() != 0) { - error->assign(file_->name()); - error->append( - ": Java MICRO_RUNTIME does not support services\""); - return false; - } - - if (found_fileName > 1) { - error->assign(file_->name()); - error->append( - ": Cannot generate Java output because there is more than one class name, \""); - error->append(classname_); - error->append( - "\", matches the name of one of the types declared inside it. " - "Please either rename the type or use the java_outer_classname " - "option to specify a different outer class name for the .proto file." - " -- FIX THIS MESSAGE"); - return false; - } - return true; -} - -void FileGenerator::Generate(io::Printer* printer) { - // We don't import anything because we refer to all classes by their - // fully-qualified names in the generated source. - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n"); - if (!java_package_.empty()) { - printer->Print( - "package $package$;\n" - "\n", - "package", java_package_); - } - - if (params_.has_java_outer_classname(file_->name())) { - printer->Print( - "public final class $classname$ {\n" - " private $classname$() {}\n", - "classname", classname_); - printer->Indent(); - } - - // ----------------------------------------------------------------- - - if (!params_.java_multiple_files()) { - for (int i = 0; i < file_->enum_type_count(); i++) { - EnumGenerator(file_->enum_type(i), params_).Generate(printer); - } - for (int i = 0; i < file_->message_type_count(); i++) { - MessageGenerator(file_->message_type(i), params_).Generate(printer); - } - } - - // Static variables. - for (int i = 0; i < file_->message_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - MessageGenerator(file_->message_type(i), params_).GenerateStaticVariables(printer); - } - - if (params_.has_java_outer_classname(file_->name())) { - printer->Outdent(); - printer->Print( - "}\n"); - } -} - -template<typename GeneratorClass, typename DescriptorClass> -static void GenerateSibling(const string& package_dir, - const string& java_package, - const DescriptorClass* descriptor, - OutputDirectory* output_directory, - vector<string>* file_list, - const Params& params) { - string filename = package_dir + descriptor->name() + ".java"; - file_list->push_back(filename); - - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(filename)); - io::Printer printer(output.get(), '$'); - - printer.Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n"); - if (!java_package.empty()) { - printer.Print( - "package $package$;\n" - "\n", - "package", java_package); - } - - GeneratorClass(descriptor, params).Generate(&printer); -} - -void FileGenerator::GenerateSiblings(const string& package_dir, - OutputDirectory* output_directory, - vector<string>* file_list) { - if (params_.java_multiple_files()) { - for (int i = 0; i < file_->enum_type_count(); i++) { - GenerateSibling<EnumGenerator>(package_dir, java_package_, - file_->enum_type(i), - output_directory, file_list, params_); - } - for (int i = 0; i < file_->message_type_count(); i++) { - GenerateSibling<MessageGenerator>(package_dir, java_package_, - file_->message_type(i), - output_directory, file_list, params_); - } - } -} - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_file.h b/src/google/protobuf/compiler/javamicro/javamicro_file.h deleted file mode 100644 index 430172a..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_file.h +++ /dev/null @@ -1,94 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ - -#include <string> -#include <vector> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/javamicro/javamicro_params.h> - -namespace google { -namespace protobuf { - class FileDescriptor; // descriptor.h - namespace io { - class Printer; // printer.h - } - namespace compiler { - class OutputDirectory; // code_generator.h - } -} - -namespace protobuf { -namespace compiler { -namespace javamicro { - -class FileGenerator { - public: - explicit FileGenerator(const FileDescriptor* file, const Params& params); - ~FileGenerator(); - - // Checks for problems that would otherwise lead to cryptic compile errors. - // Returns true if there are no problems, or writes an error description to - // the given string and returns false otherwise. - bool Validate(string* error); - - void Generate(io::Printer* printer); - - // If we aren't putting everything into one file, this will write all the - // files other than the outer file (i.e. one for each message, enum, and - // service type). - void GenerateSiblings(const string& package_dir, - OutputDirectory* output_directory, - vector<string>* file_list); - - const string& java_package() { return java_package_; } - const string& classname() { return classname_; } - - private: - const FileDescriptor* file_; - const Params& params_; - string java_package_; - string classname_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); -}; - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_generator.cc b/src/google/protobuf/compiler/javamicro/javamicro_generator.cc deleted file mode 100644 index bfba8c5..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_generator.cc +++ /dev/null @@ -1,209 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/javamicro/javamicro_params.h> -#include <google/protobuf/compiler/javamicro/javamicro_generator.h> -#include <google/protobuf/compiler/javamicro/javamicro_file.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -void UpdateParamsRecursively(Params& params, - const FileDescriptor* file) { - // Add any parameters for this file - if (file->options().has_java_outer_classname()) { - params.set_java_outer_classname( - file->name(), file->options().java_outer_classname()); - } - if (file->options().has_java_package()) { - params.set_java_package( - file->name(), file->options().java_package()); - } - - // Loop through all dependent files recursively - // adding dep - for (int i = 0; i < file->dependency_count(); i++) { - UpdateParamsRecursively(params, file->dependency(i)); - } -} - -JavaMicroGenerator::JavaMicroGenerator() {} -JavaMicroGenerator::~JavaMicroGenerator() {} - -bool JavaMicroGenerator::Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - vector<pair<string, string> > options; - -// GOOGLE_LOG(INFO) << "wink: JavaMicroGenerator::Generate INFO"; -// GOOGLE_LOG(WARNING) << "wink: JavaMicroGenerator::Generate WARNING"; -// GOOGLE_LOG(ERROR) << "wink: JavaMicroGenerator::Generate ERROR"; -// GOOGLE_LOG(FATAL) << "wink: JavaMicroGenerator::Generate"; - - ParseGeneratorParameter(parameter, &options); - - // ----------------------------------------------------------------- - // parse generator options - - // Name a file where we will write a list of generated file names, one - // per line. - string output_list_file; - Params params(file->name()); - - // Get options from the proto file - if (file->options().has_java_multiple_files()) { - params.set_java_multiple_files(file->options().java_multiple_files()); - } - - // Update per file params - UpdateParamsRecursively(params, file); - - // Replace any existing options with ones from command line - for (int i = 0; i < options.size(); i++) { - // GOOGLE_LOG(WARNING) << "first=" << options[i].first - // << " second=" << options[i].second; - if (options[i].first == "output_list_file") { - output_list_file = options[i].second; - } else if (options[i].first == "opt") { - if (options[i].second == "speed") { - params.set_optimization(JAVAMICRO_OPT_SPEED); - } else if (options[i].second == "space") { - params.set_optimization(JAVAMICRO_OPT_SPACE); - } else { - *error = "Unknown javamicro generator option: opt=" - + options[i].second + " expecting opt=space or opt=speed"; - return false; - } - } else if (options[i].first == "java_package") { - vector<string> parts; - SplitStringUsing(options[i].second, "|", &parts); - if (parts.size() != 2) { - *error = "Bad java_package, expecting filename|PackageName found '" - + options[i].second + "'"; - return false; - } - params.set_java_package(parts[0], parts[1]); - } else if (options[i].first == "java_outer_classname") { - vector<string> parts; - SplitStringUsing(options[i].second, "|", &parts); - if (parts.size() != 2) { - *error = "Bad java_outer_classname, " - "expecting filename|ClassName found '" - + options[i].second + "'"; - return false; - } - params.set_java_outer_classname(parts[0], parts[1]); - } else if (options[i].first == "java_multiple_files") { - params.set_java_multiple_files(options[i].second == "true"); - } else if (options[i].first == "java_use_vector") { - params.set_java_use_vector(options[i].second == "true"); - } else { - *error = "Ignore unknown javamicro generator option: " + options[i].first; - } - } - -#if 0 - GOOGLE_LOG(WARNING) << "optimization()=" << params.optimization(); - GOOGLE_LOG(WARNING) << "java_multiple_files()=" << params.java_multiple_files(); - GOOGLE_LOG(WARNING) << "java_use_vector()=" << params.java_use_vector(); - - GOOGLE_LOG(WARNING) << "----------"; - for (Params::NameMap::const_iterator it = params.java_packages().begin(); - it != params.java_packages().end(); - ++it) { - GOOGLE_LOG(WARNING) << "cn.filename=" << it->first << " package=" << it->second; - } - for (Params::NameMap::const_iterator it = params.java_outer_classnames().begin(); - it != params.java_outer_classnames().end(); - ++it) { - GOOGLE_LOG(WARNING) << "cn.filename=" << it->first << " classname=" << it->second; - } - GOOGLE_LOG(WARNING) << "=========="; - -#endif - - // ----------------------------------------------------------------- - - FileGenerator file_generator(file, params); - if (!file_generator.Validate(error)) { - return false; - } - - string package_dir = - StringReplace(file_generator.java_package(), ".", "/", true); - if (!package_dir.empty()) package_dir += "/"; - - vector<string> all_files; - - string java_filename = package_dir; - java_filename += file_generator.classname(); - java_filename += ".java"; - all_files.push_back(java_filename); - - // Generate main java file. - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(java_filename)); - io::Printer printer(output.get(), '$'); - file_generator.Generate(&printer); - - // Generate sibling files. - file_generator.GenerateSiblings(package_dir, output_directory, &all_files); - - // Generate output list if requested. - if (!output_list_file.empty()) { - // Generate output list. This is just a simple text file placed in a - // deterministic location which lists the .java files being generated. - scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output( - output_directory->Open(output_list_file)); - io::Printer srclist_printer(srclist_raw_output.get(), '$'); - for (int i = 0; i < all_files.size(); i++) { - srclist_printer.Print("$filename$\n", "filename", all_files[i]); - } - } - - return true; -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc b/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc deleted file mode 100644 index 11ba71a..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc +++ /dev/null @@ -1,381 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <vector> - -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/compiler/javamicro/javamicro_params.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -const char kThickSeparator[] = - "// ===================================================================\n"; -const char kThinSeparator[] = - "// -------------------------------------------------------------------\n"; - -namespace { - -const char* kDefaultPackage = ""; - -const string& FieldName(const FieldDescriptor* field) { - // Groups are hacky: The name of the field is just the lower-cased name - // of the group type. In Java, though, we would like to retain the original - // capitalization of the type name. - if (field->type() == FieldDescriptor::TYPE_GROUP) { - return field->message_type()->name(); - } else { - return field->name(); - } -} - -string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) { - string result; - // Note: I distrust ctype.h due to locales. - for (int i = 0; i < input.size(); i++) { - if ('a' <= input[i] && input[i] <= 'z') { - if (cap_next_letter) { - result += input[i] + ('A' - 'a'); - } else { - result += input[i]; - } - cap_next_letter = false; - } else if ('A' <= input[i] && input[i] <= 'Z') { - if (i == 0 && !cap_next_letter) { - // Force first letter to lower-case unless explicitly told to - // capitalize it. - result += input[i] + ('a' - 'A'); - } else { - // Capital letters after the first are left as-is. - result += input[i]; - } - cap_next_letter = false; - } else if ('0' <= input[i] && input[i] <= '9') { - result += input[i]; - cap_next_letter = true; - } else { - cap_next_letter = true; - } - } - return result; -} - -} // namespace - -string UnderscoresToCamelCase(const FieldDescriptor* field) { - return UnderscoresToCamelCaseImpl(FieldName(field), false); -} - -string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { - return UnderscoresToCamelCaseImpl(FieldName(field), true); -} - -string UnderscoresToCamelCase(const MethodDescriptor* method) { - return UnderscoresToCamelCaseImpl(method->name(), false); -} - -string StripProto(const string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - -string FileClassName(const Params& params, const FileDescriptor* file) { - string name; - - if (params.has_java_outer_classname(file->name())) { - name = params.java_outer_classname(file->name()); - } else { - if ((file->message_type_count() == 1) - || (file->enum_type_count() == 0)) { - // If no outer calls and only one message then - // use the message name as the file name - name = file->message_type(0)->name(); - } else { - // Use the filename it self with underscores removed - // and a CamelCase style name. - string basename; - string::size_type last_slash = file->name().find_last_of('/'); - if (last_slash == string::npos) { - basename = file->name(); - } else { - basename = file->name().substr(last_slash + 1); - } - name = UnderscoresToCamelCaseImpl(StripProto(basename), true); - } - } - - return name; -} - -string FileJavaPackage(const Params& params, const FileDescriptor* file) { - if (params.has_java_package(file->name())) { - return params.java_package(file->name()); - } else { - string result = kDefaultPackage; - if (!file->package().empty()) { - if (!result.empty()) result += '.'; - result += file->package(); - } - return result; - } -} - -string ToJavaName(const Params& params, const string& full_name, - const FileDescriptor* file) { - string result; - if (params.java_multiple_files()) { - result = FileJavaPackage(params, file); - } else { - result = ClassName(params, file); - } - if (file->package().empty()) { - result += '.'; - result += full_name; - } else { - // Strip the proto package from full_name since we've replaced it with - // the Java package. If there isn't an outer classname then strip it too. - int sizeToSkipPackageName = file->package().size(); - int sizeToSkipOutClassName; - if (params.has_java_outer_classname(file->name())) { - sizeToSkipOutClassName = 0; - } else { - sizeToSkipOutClassName = - full_name.find_first_of('.', sizeToSkipPackageName + 1); - } - int sizeToSkip = sizeToSkipOutClassName > 0 ? - sizeToSkipOutClassName : sizeToSkipPackageName; - string class_name = full_name.substr(sizeToSkip + 1); - if (class_name == FileClassName(params, file)) { - // Done class_name is already present. - } else { - result += '.'; - result += class_name; - } - } - return result; -} - -string ClassName(const Params& params, const FileDescriptor* descriptor) { - string result = FileJavaPackage(params, descriptor); - if (!result.empty()) result += '.'; - result += FileClassName(params, descriptor); - return result; -} - -string ClassName(const Params& params, const EnumDescriptor* descriptor) { - string result; - const FileDescriptor* file = descriptor->file(); - const string file_name = file->name(); - const string full_name = descriptor->full_name(); - int last_period = full_name.find_last_of('.'); - int first_period = full_name.find_first_of('.'); - - // Remove class_name as we're using public static final int's not enums - string base_name = full_name.substr(0, full_name.find_last_of('.')); - - if (!file->package().empty()) { - // Remove package name. - int offset = first_period; - if (last_period > first_period) { - // There was two or more periods so we need to remove this one too. - offset += 1; - } - base_name = base_name.substr(offset); - } - - if (params.has_java_package(file_name)) { - result += params.java_package(file_name); - } - if (params.has_java_outer_classname(file_name)) { - result += "."; - result += params.java_outer_classname(file_name); - } - if (!base_name.empty()) { - result += "."; - result += base_name; - } - return result; -} - -string FieldConstantName(const FieldDescriptor *field) { - string name = field->name() + "_FIELD_NUMBER"; - UpperString(&name); - return name; -} - -JavaType GetJavaType(FieldDescriptor::Type field_type) { - switch (field_type) { - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_SFIXED32: - return JAVATYPE_INT; - - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_SFIXED64: - return JAVATYPE_LONG; - - case FieldDescriptor::TYPE_FLOAT: - return JAVATYPE_FLOAT; - - case FieldDescriptor::TYPE_DOUBLE: - return JAVATYPE_DOUBLE; - - case FieldDescriptor::TYPE_BOOL: - return JAVATYPE_BOOLEAN; - - case FieldDescriptor::TYPE_STRING: - return JAVATYPE_STRING; - - case FieldDescriptor::TYPE_BYTES: - return JAVATYPE_BYTES; - - case FieldDescriptor::TYPE_ENUM: - return JAVATYPE_ENUM; - - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - return JAVATYPE_MESSAGE; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return JAVATYPE_INT; -} - -const char* BoxedPrimitiveTypeName(JavaType type) { - switch (type) { - case JAVATYPE_INT : return "java.lang.Integer"; - case JAVATYPE_LONG : return "java.lang.Long"; - case JAVATYPE_FLOAT : return "java.lang.Float"; - case JAVATYPE_DOUBLE : return "java.lang.Double"; - case JAVATYPE_BOOLEAN: return "java.lang.Boolean"; - case JAVATYPE_STRING : return "java.lang.String"; - case JAVATYPE_BYTES : return "com.google.protobuf.micro.ByteStringMicro"; - case JAVATYPE_ENUM : return "java.lang.Integer"; - case JAVATYPE_MESSAGE: return NULL; - - // No default because we want the compiler to complain if any new - // JavaTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -bool AllAscii(const string& text) { - for (int i = 0; i < text.size(); i++) { - if ((text[i] & 0x80) != 0) { - return false; - } - } - return true; -} - -string DefaultValue(const Params& params, const FieldDescriptor* field) { - // Switch on cpp_type since we need to know which default_value_* method - // of FieldDescriptor to call. - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return SimpleItoa(field->default_value_int32()); - case FieldDescriptor::CPPTYPE_UINT32: - // Need to print as a signed int since Java has no unsigned. - return SimpleItoa(static_cast<int32>(field->default_value_uint32())); - case FieldDescriptor::CPPTYPE_INT64: - return SimpleItoa(field->default_value_int64()) + "L"; - case FieldDescriptor::CPPTYPE_UINT64: - return SimpleItoa(static_cast<int64>(field->default_value_uint64())) + - "L"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field->default_value_double()) + "D"; - case FieldDescriptor::CPPTYPE_FLOAT: - return SimpleFtoa(field->default_value_float()) + "F"; - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "true" : "false"; - case FieldDescriptor::CPPTYPE_STRING: - if (field->type() == FieldDescriptor::TYPE_BYTES) { - if (field->has_default_value()) { - // See comments in Internal.java for gory details. - return strings::Substitute( - "com.google.protobuf.micro.ByteStringMicro.copyFromUtf8(\"$0\")", - CEscape(field->default_value_string())); - } else { - return "com.google.protobuf.micro.ByteStringMicro.EMPTY"; - } - } else { - if (AllAscii(field->default_value_string())) { - // All chars are ASCII. In this case CEscape() works fine. - return "\"" + CEscape(field->default_value_string()) + "\""; - } else { - // See comments in Internal.java for gory details. - // BUG: Internal NOT SUPPORTED need to fix!! - return strings::Substitute( - "com.google.protobuf.micro.Internal.stringDefaultValue(\"$0\")", - CEscape(field->default_value_string())); - } - } - - case FieldDescriptor::CPPTYPE_ENUM: - return ClassName(params, field->enum_type()) + "." + - field->default_value_enum()->name(); - - case FieldDescriptor::CPPTYPE_MESSAGE: - return ClassName(params, field->message_type()) + ".getDefaultInstance()"; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return ""; -} - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_helpers.h b/src/google/protobuf/compiler/javamicro/javamicro_helpers.h deleted file mode 100644 index eeddbf9..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_helpers.h +++ /dev/null @@ -1,128 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ - -#include <string> -#include <google/protobuf/compiler/javamicro/javamicro_params.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -// Commonly-used separator comments. Thick is a line of '=', thin is a line -// of '-'. -extern const char kThickSeparator[]; -extern const char kThinSeparator[]; - -// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes -// "fooBarBaz" or "FooBarBaz", respectively. -string UnderscoresToCamelCase(const FieldDescriptor* field); -string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); - -// Similar, but for method names. (Typically, this merely has the effect -// of lower-casing the first letter of the name.) -string UnderscoresToCamelCase(const MethodDescriptor* method); - -// Strips ".proto" or ".protodevel" from the end of a filename. -string StripProto(const string& filename); - -// Gets the unqualified class name for the file. Each .proto file becomes a -// single Java class, with all its contents nested in that class. -string FileClassName(const Params& params, const FileDescriptor* file); - -// Returns the file's Java package name. -string FileJavaPackage(const Params& params, const FileDescriptor* file); - -// Converts the given fully-qualified name in the proto namespace to its -// fully-qualified name in the Java namespace, given that it is in the given -// file. -string ToJavaName(const Params& params, const string& full_name, - const FileDescriptor* file); - -// These return the fully-qualified class name corresponding to the given -// descriptor. -inline string ClassName(const Params& params, const Descriptor* descriptor) { - return ToJavaName(params, descriptor->full_name(), descriptor->file()); -} -string ClassName(const Params& params, const EnumDescriptor* descriptor); -inline string ClassName(const Params& params, - const ServiceDescriptor* descriptor) { - return ToJavaName(params, descriptor->full_name(), descriptor->file()); -} -inline string ExtensionIdentifierName(const Params& params, - const FieldDescriptor* descriptor) { - return ToJavaName(params, descriptor->full_name(), descriptor->file()); -} -string ClassName(const Params& params, const FileDescriptor* descriptor); - -// Get the unqualified name that should be used for a field's field -// number constant. -string FieldConstantName(const FieldDescriptor *field); - -enum JavaType { - JAVATYPE_INT, - JAVATYPE_LONG, - JAVATYPE_FLOAT, - JAVATYPE_DOUBLE, - JAVATYPE_BOOLEAN, - JAVATYPE_STRING, - JAVATYPE_BYTES, - JAVATYPE_ENUM, - JAVATYPE_MESSAGE -}; - -JavaType GetJavaType(FieldDescriptor::Type field_type); - -inline JavaType GetJavaType(const FieldDescriptor* field) { - return GetJavaType(field->type()); -} - -// Get the fully-qualified class name for a boxed primitive type, e.g. -// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message -// types. -const char* BoxedPrimitiveTypeName(JavaType type); - -string DefaultValue(const Params& params, const FieldDescriptor* field); - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message.cc b/src/google/protobuf/compiler/javamicro/javamicro_message.cc deleted file mode 100644 index 7fc6c3d..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_message.cc +++ /dev/null @@ -1,474 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <algorithm> -#include <google/protobuf/stubs/hash.h> -#include <google/protobuf/compiler/javamicro/javamicro_message.h> -#include <google/protobuf/compiler/javamicro/javamicro_enum.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/descriptor.pb.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -using internal::WireFormat; -using internal::WireFormatLite; - -namespace { - -void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { - // Print the field's proto-syntax definition as a comment. We don't want to - // print group bodies so we cut off after the first line. - string def = field->DebugString(); - printer->Print("// $def$\n", - "def", def.substr(0, def.find_first_of('\n'))); -} - -struct FieldOrderingByNumber { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) const { - return a->number() < b->number(); - } -}; - -// Sort the fields of the given Descriptor by number into a new[]'d array -// and return it. -const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { - const FieldDescriptor** fields = - new const FieldDescriptor*[descriptor->field_count()]; - for (int i = 0; i < descriptor->field_count(); i++) { - fields[i] = descriptor->field(i); - } - sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); - return fields; -} - -// Get an identifier that uniquely identifies this type within the file. -// This is used to declare static variables related to this type at the -// outermost file scope. -string UniqueFileScopeIdentifier(const Descriptor* descriptor) { - return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); -} - -// Returns true if the message type has any required fields. If it doesn't, -// we can optimize out calls to its isInitialized() method. -// -// already_seen is used to avoid checking the same type multiple times -// (and also to protect against recursion). -static bool HasRequiredFields( - const Descriptor* type, - hash_set<const Descriptor*>* already_seen) { - if (already_seen->count(type) > 0) { - // The type is already in cache. This means that either: - // a. The type has no required fields. - // b. We are in the midst of checking if the type has required fields, - // somewhere up the stack. In this case, we know that if the type - // has any required fields, they'll be found when we return to it, - // and the whole call to HasRequiredFields() will return true. - // Therefore, we don't have to check if this type has required fields - // here. - return false; - } - already_seen->insert(type); - - // If the type has extensions, an extension with message type could contain - // required fields, so we have to be conservative and assume such an - // extension exists. - if (type->extension_range_count() > 0) return true; - - for (int i = 0; i < type->field_count(); i++) { - const FieldDescriptor* field = type->field(i); - if (field->is_required()) { - return true; - } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (HasRequiredFields(field->message_type(), already_seen)) { - return true; - } - } - } - - return false; -} - -static bool HasRequiredFields(const Descriptor* type) { - hash_set<const Descriptor*> already_seen; - return HasRequiredFields(type, &already_seen); -} - -} // namespace - -// =================================================================== - -MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params) - : params_(params), - descriptor_(descriptor), - field_generators_(descriptor, params) { -} - -MessageGenerator::~MessageGenerator() {} - -void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { - // Generate static members for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - MessageGenerator(descriptor_->nested_type(i), params_) - .GenerateStaticVariables(printer); - } -} - -void MessageGenerator::GenerateStaticVariableInitializers( - io::Printer* printer) { - // Generate static member initializers for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - MessageGenerator(descriptor_->nested_type(i), params_) - .GenerateStaticVariableInitializers(printer); - } - - if (descriptor_->extension_count() != 0) { - GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n"; - } -} - -void MessageGenerator::Generate(io::Printer* printer) { - bool is_own_file = - params_.java_multiple_files() || ((descriptor_->containing_type() == NULL) - && !params_.has_java_outer_classname(descriptor_->file()->name())); - -#if 0 - GOOGLE_LOG(INFO) << "is_own_file=" << is_own_file; - GOOGLE_LOG(INFO) << "containing_type()=" << ((descriptor_->containing_type() == NULL) ? "NULL" : "not null"); - GOOGLE_LOG(INFO) << "java_multiple_files()=" << params_.java_multiple_files(); - GOOGLE_LOG(INFO) << "has_java_outer_classname()=" << params_.has_java_outer_classname(file_->name()); -#endif - - if ((descriptor_->extension_count() != 0) - || (descriptor_->extension_range_count() != 0)) { - GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n"; - } - - printer->Print( - "public $modifiers$ final class $classname$ extends\n" - " com.google.protobuf.micro.MessageMicro {\n", - "modifiers", is_own_file ? "" : "static", - "classname", descriptor_->name()); - printer->Indent(); - printer->Print( - "public $classname$() {}\n" - "\n", - "classname", descriptor_->name()); - - // Nested types and extensions - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer); - } - - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer); - } - - // Fields - for (int i = 0; i < descriptor_->field_count(); i++) { - PrintFieldComment(printer, descriptor_->field(i)); - printer->Print("public static final int $constant_name$ = $number$;\n", - "constant_name", FieldConstantName(descriptor_->field(i)), - "number", SimpleItoa(descriptor_->field(i)->number())); - field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); - printer->Print("\n"); - } - - GenerateClear(printer); - GenerateIsInitialized(printer); - GenerateMessageSerializationMethods(printer); - GenerateMergeFromMethods(printer); - GenerateParseFromMethods(printer); - - printer->Outdent(); - printer->Print("}\n\n"); -} - -// =================================================================== - -void MessageGenerator:: -GenerateMessageSerializationMethods(io::Printer* printer) { - scoped_array<const FieldDescriptor*> sorted_fields( - SortFieldsByNumber(descriptor_)); - - if (descriptor_->extension_range_count() != 0) { - GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n"; - } - - printer->Print( - "public void writeTo(com.google.protobuf.micro.CodedOutputStreamMicro output)\n" - " throws java.io.IOException {\n"); - printer->Indent(); - - // Output the fields in sorted order - for (int i = 0; i < descriptor_->field_count(); i++) { - GenerateSerializeOneField(printer, sorted_fields[i]); - } - - printer->Outdent(); - printer->Print( - "}\n" - "\n" - "private int cachedSize = -1;\n" - "public int getCachedSize() {\n" - " if (cachedSize < 0) {\n" - " // getSerializedSize sets cachedSize\n" - " getSerializedSize();\n" - " }\n" - " return cachedSize;\n" - "}\n" - "\n" - "public int getSerializedSize() {\n" - " int size = 0;\n"); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); - } - - printer->Outdent(); - printer->Print( - " cachedSize = size;\n" - " return size;\n" - "}\n" - "\n"); -} - -void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) { - scoped_array<const FieldDescriptor*> sorted_fields( - SortFieldsByNumber(descriptor_)); - - if (params_.java_use_vector()) { - printer->Print( - "public com.google.protobuf.micro.MessageMicro mergeFrom(\n" - " com.google.protobuf.micro.CodedInputStreamMicro input)\n" - " throws java.io.IOException {\n", - "classname", descriptor_->name()); - } else { - printer->Print( - "public $classname$ mergeFrom(\n" - " com.google.protobuf.micro.CodedInputStreamMicro input)\n" - " throws java.io.IOException {\n", - "classname", descriptor_->name()); - } - printer->Indent(); - - printer->Print( - "while (true) {\n"); - printer->Indent(); - - printer->Print( - "int tag = input.readTag();\n" - "switch (tag) {\n"); - printer->Indent(); - - printer->Print( - "case 0:\n" // zero signals EOF / limit reached - " return this;\n" - "default: {\n" - " if (!parseUnknownField(input, tag)) {\n" - " return this;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = sorted_fields[i]; - uint32 tag = WireFormatLite::MakeTag(field->number(), - WireFormat::WireTypeForField(field)); - - printer->Print( - "case $tag$: {\n", - "tag", SimpleItoa(tag)); - printer->Indent(); - - field_generators_.get(field).GenerateParsingCode(printer); - - printer->Outdent(); - printer->Print( - " break;\n" - "}\n"); - } - - printer->Outdent(); - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\n" // switch (tag) - " }\n" // while (true) - "}\n" - "\n"); -} - -void MessageGenerator:: -GenerateParseFromMethods(io::Printer* printer) { - bool is_own_file = - descriptor_->containing_type() == NULL; - - // Note: These are separate from GenerateMessageSerializationMethods() - // because they need to be generated even for messages that are optimized - // for code size. - printer->Print( - "public $static$ $classname$ parseFrom(byte[] data)\n" - " throws com.google.protobuf.micro.InvalidProtocolBufferMicroException {\n" - " return ($classname$) (new $classname$().mergeFrom(data));\n" - "}\n" - "\n" - "public $static$ $classname$ parseFrom(\n" - " com.google.protobuf.micro.CodedInputStreamMicro input)\n" - " throws java.io.IOException {\n" - " return ($classname$) (new $classname$().mergeFrom(input));\n" - "}\n" - "\n", - "static", (is_own_file ? "static" : ""), - "classname", descriptor_->name()); -} - -void MessageGenerator::GenerateSerializeOneField( - io::Printer* printer, const FieldDescriptor* field) { - field_generators_.get(field).GenerateSerializationCode(printer); -} - -void MessageGenerator::GenerateClear(io::Printer* printer) { - printer->Print( - "public final $classname$ clear() {\n", - "classname", descriptor_->name()); - printer->Indent(); - - // Call clear for all of the fields. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - printer->Print( - "clear$name$();\n", - "name", UnderscoresToCapitalizedCamelCase(field)); - } - - printer->Outdent(); - printer->Print( - " cachedSize = -1;\n" - " return this;\n" - "}\n" - "\n"); -} - - -void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { - printer->Print( - "public final boolean isInitialized() {\n"); - printer->Indent(); - - // Check that all required fields in this message are set. - // TODO(kenton): We can optimize this when we switch to putting all the - // "has" fields into a single bitfield. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->is_required()) { - printer->Print( - "if (!has$name$) return false;\n", - "name", UnderscoresToCapitalizedCamelCase(field)); - } - } - - // Now check that all embedded messages are initialized. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - HasRequiredFields(field->message_type())) { - switch (field->label()) { - case FieldDescriptor::LABEL_REQUIRED: - printer->Print( - "if (!get$name$().isInitialized()) return false;\n", - "type", ClassName(params_, field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - case FieldDescriptor::LABEL_OPTIONAL: - printer->Print( - "if (has$name$()) {\n" - " if (!get$name$().isInitialized()) return false;\n" - "}\n", - "type", ClassName(params_, field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - case FieldDescriptor::LABEL_REPEATED: - if (params_.java_use_vector()) { - printer->Print( - "for (int i = 0; i < get$name$List().size(); i++) {\n" - " if (get$name$(i).isInitialized()) return false;\n" - "}\n", - "type", ClassName(params_, field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - } else { - printer->Print( - "for ($type$ element : get$name$List()) {\n" - " if (!element.isInitialized()) return false;\n" - "}\n", - "type", ClassName(params_, field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - } - break; - } - } - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "if (!extensionsAreInitialized()) return false;\n"); - } - - printer->Outdent(); - printer->Print( - " return true;\n" - "}\n" - "\n"); -} - -// =================================================================== - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message.h b/src/google/protobuf/compiler/javamicro/javamicro_message.h deleted file mode 100644 index f44c7a7..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_message.h +++ /dev/null @@ -1,93 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/javamicro/javamicro_params.h> -#include <google/protobuf/compiler/javamicro/javamicro_field.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace javamicro { - -class MessageGenerator { - public: - explicit MessageGenerator(const Descriptor* descriptor, const Params& params); - ~MessageGenerator(); - - // All static variables have to be declared at the top-level of the file - // so that we can control initialization order, which is important for - // DescriptorProto bootstrapping to work. - void GenerateStaticVariables(io::Printer* printer); - - // Output code which initializes the static variables generated by - // GenerateStaticVariables(). - void GenerateStaticVariableInitializers(io::Printer* printer); - - // Generate the class itself. - void Generate(io::Printer* printer); - - private: - void GenerateMessageSerializationMethods(io::Printer* printer); - void GenerateMergeFromMethods(io::Printer* printer); - void GenerateParseFromMethods(io::Printer* printer); - void GenerateSerializeOneField(io::Printer* printer, - const FieldDescriptor* field); - - void GenerateClear(io::Printer* printer); - void GenerateIsInitialized(io::Printer* printer); - - const Params& params_; - const Descriptor* descriptor_; - FieldGeneratorMap field_generators_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); -}; - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc deleted file mode 100644 index 103c302..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc +++ /dev/null @@ -1,302 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/javamicro/javamicro_message_field.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -namespace { - -// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of -// repeat code between this and the other field types. -void SetMessageVariables(const Params& params, - const FieldDescriptor* descriptor, map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = ClassName(params, descriptor->message_type()); - (*variables)["group_or_message"] = - (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? - "Group" : "Message"; - (*variables)["message_name"] = descriptor->containing_type()->name(); - //(*variables)["message_type"] = descriptor->message_type()->name(); -} - -} // namespace - -// =================================================================== - -MessageFieldGenerator:: -MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) - : FieldGenerator(params), descriptor_(descriptor) { - SetMessageVariables(params, descriptor, &variables_); -} - -MessageFieldGenerator::~MessageFieldGenerator() {} - -void MessageFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private boolean has$capitalized_name$;\n" -// "private $type$ $name$_ = null;\n" -// "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" -// "public $type$ get$capitalized_name$() { return $name$_; }\n" - "private $type$ $name$_ = null;\n" - "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" - "public $type$ get$capitalized_name$() { return $name$_; }\n" - "public $message_name$ set$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " has$capitalized_name$ = true;\n" - " $name$_ = value;\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " has$capitalized_name$ = false;\n" - " $name$_ = null;\n" - " return this;\n" - "}\n"); -} - -void MessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.has$capitalized_name$()) {\n" - " merge$capitalized_name$(other.get$capitalized_name$());\n" - "}\n"); -} - -void MessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$type$ value = new $type$();\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { - printer->Print(variables_, - "input.readGroup(value, $number$);\n"); - } else { - printer->Print(variables_, - "input.readMessage(value);\n"); - } - - printer->Print(variables_, - "set$capitalized_name$(value);\n"); -} - -void MessageFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.write$group_or_message$($number$, get$capitalized_name$());\n" - "}\n"); -} - -void MessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" - "}\n"); -} - -string MessageFieldGenerator::GetBoxedType() const { - return ClassName(params_, descriptor_->message_type()); -} - -// =================================================================== - -RepeatedMessageFieldGenerator:: -RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) - : FieldGenerator(params), descriptor_(descriptor) { - SetMessageVariables(params, descriptor, &variables_); -} - -RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} - -void RepeatedMessageFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - if (params_.java_use_vector()) { - printer->Print(variables_, - "private java.util.Vector $name$_ = new java.util.Vector();\n" - "public java.util.Vector get$capitalized_name$List() {\n" - " return $name$_;\n" - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return ($type$) $name$_.elementAt(index);\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " $name$_.setElementAt(value, index);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " $name$_.addElement(value);\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_.removeAllElements();\n" - " return this;\n" - "}\n"); - } else { - printer->Print(variables_, - "private java.util.List<$type$> $name$_ =\n" - " java.util.Collections.emptyList();\n" - "public java.util.List<$type$> get$capitalized_name$List() {\n" - " return $name$_;\n" - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return $name$_.get(index);\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " $name$_.set(index, value);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " if ($name$_.isEmpty()) {\n" - " $name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " $name$_.add(value);\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); - } -} - -void RepeatedMessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - if (params_.java_use_vector()) { - printer->Print(variables_, - "if (other.$name$_.size() != 0) {\n" - " for (int i = 0; i < other.$name$_.size(); i++) {\n" - " result.$name$_.addElement(other.$name$_.elementAt(i));\n" - " }\n" - "}\n"); - } else { - printer->Print(variables_, - "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.addAll(other.$name$_);\n" - "}\n"); - } -} - -void RepeatedMessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$type$ value = new $type$();\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { - printer->Print(variables_, - "input.readGroup(value, $number$);\n"); - } else { - printer->Print(variables_, - "input.readMessage(value);\n"); - } - - printer->Print(variables_, - "add$capitalized_name$(value);\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - if (params_.java_use_vector()) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " output.write$group_or_message$($number$, get$capitalized_name$(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.write$group_or_message$($number$, element);\n" - "}\n"); - } -} - -void RepeatedMessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - if (params_.java_use_vector()) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .compute$group_or_message$Size($number$, get$capitalized_name$(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .compute$group_or_message$Size($number$, element);\n" - "}\n"); - } -} - -string RepeatedMessageFieldGenerator::GetBoxedType() const { - return ClassName(params_, descriptor_->message_type()); -} - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message_field.h b/src/google/protobuf/compiler/javamicro/javamicro_message_field.h deleted file mode 100644 index a32aa4e..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_message_field.h +++ /dev/null @@ -1,95 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/javamicro/javamicro_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -class MessageFieldGenerator : public FieldGenerator { - public: - explicit MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params); - ~MessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); -}; - -class RepeatedMessageFieldGenerator : public FieldGenerator { - public: - explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Params& params); - ~RepeatedMessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); -}; - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_params.h b/src/google/protobuf/compiler/javamicro/javamicro_params.h deleted file mode 100644 index a4a72b7..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_params.h +++ /dev/null @@ -1,143 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2010 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: wink@google.com (Wink Saville) - -#ifndef PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_ -#define PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_ - -#include <map> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -enum eOptimization { JAVAMICRO_OPT_SPEED, JAVAMICRO_OPT_SPACE, JAVAMICRO_OPT_DEFAULT = JAVAMICRO_OPT_SPACE }; - -// Parameters for used by the generators -class Params { - public: - typedef map<string, string> NameMap; - private: - string empty_; - string base_name_; - eOptimization optimization_; - bool java_multiple_files_; - bool java_use_vector_; - NameMap java_packages_; - NameMap java_outer_classnames_; - - public: - Params(const string & base_name) : - empty_(""), - base_name_(base_name), - optimization_(JAVAMICRO_OPT_DEFAULT), - java_multiple_files_(false), - java_use_vector_(false) { - } - - const string& base_name() const { - return base_name_; - } - - bool has_java_package(const string& file_name) const { - return java_packages_.find(file_name) - != java_packages_.end(); - } - void set_java_package(const string& file_name, - const string& java_package) { - java_packages_[file_name] = java_package; - } - const string& java_package(const string& file_name) const { - NameMap::const_iterator itr; - - itr = java_packages_.find(file_name); - if (itr == java_packages_.end()) { - return empty_; - } else { - return itr->second; - } - } - const NameMap& java_packages() { - return java_packages_; - } - - bool has_java_outer_classname(const string& file_name) const { - return java_outer_classnames_.find(file_name) - != java_outer_classnames_.end(); - } - void set_java_outer_classname(const string& file_name, - const string& java_outer_classname) { - java_outer_classnames_[file_name] = java_outer_classname; - } - const string& java_outer_classname(const string& file_name) const { - NameMap::const_iterator itr; - - itr = java_outer_classnames_.find(file_name); - if (itr == java_outer_classnames_.end()) { - return empty_; - } else { - return itr->second; - } - } - const NameMap& java_outer_classnames() { - return java_outer_classnames_; - } - - void set_optimization(eOptimization optimization) { - optimization_ = optimization; - } - eOptimization optimization() const { - return optimization_; - } - - void set_java_multiple_files(bool value) { - java_multiple_files_ = value; - } - bool java_multiple_files() const { - return java_multiple_files_; - } - - void set_java_use_vector(bool value) { - java_use_vector_ = value; - } - bool java_use_vector() const { - return java_use_vector_; - } - -}; - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google -#endif // PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc deleted file mode 100644 index d6daa44..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc +++ /dev/null @@ -1,660 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/javamicro/javamicro_primitive_field.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -using internal::WireFormat; -using internal::WireFormatLite; - -namespace { - -const char* PrimitiveTypeName(JavaType type) { - switch (type) { - case JAVATYPE_INT : return "int"; - case JAVATYPE_LONG : return "long"; - case JAVATYPE_FLOAT : return "float"; - case JAVATYPE_DOUBLE : return "double"; - case JAVATYPE_BOOLEAN: return "boolean"; - case JAVATYPE_STRING : return "java.lang.String"; - case JAVATYPE_BYTES : return "com.google.protobuf.micro.ByteStringMicro"; - case JAVATYPE_ENUM : return NULL; - case JAVATYPE_MESSAGE: return NULL; - - // No default because we want the compiler to complain if any new - // JavaTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -bool IsReferenceType(JavaType type) { - switch (type) { - case JAVATYPE_INT : return false; - case JAVATYPE_LONG : return false; - case JAVATYPE_FLOAT : return false; - case JAVATYPE_DOUBLE : return false; - case JAVATYPE_BOOLEAN: return false; - case JAVATYPE_STRING : return true; - case JAVATYPE_BYTES : return true; - case JAVATYPE_ENUM : return false; - case JAVATYPE_MESSAGE: return true; - - // No default because we want the compiler to complain if any new - // JavaTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return false; -} - -const char* GetCapitalizedType(const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_INT32 : return "Int32" ; - case FieldDescriptor::TYPE_UINT32 : return "UInt32" ; - case FieldDescriptor::TYPE_SINT32 : return "SInt32" ; - case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ; - case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; - case FieldDescriptor::TYPE_INT64 : return "Int64" ; - case FieldDescriptor::TYPE_UINT64 : return "UInt64" ; - case FieldDescriptor::TYPE_SINT64 : return "SInt64" ; - case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ; - case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; - case FieldDescriptor::TYPE_FLOAT : return "Float" ; - case FieldDescriptor::TYPE_DOUBLE : return "Double" ; - case FieldDescriptor::TYPE_BOOL : return "Bool" ; - case FieldDescriptor::TYPE_STRING : return "String" ; - case FieldDescriptor::TYPE_BYTES : return "Bytes" ; - case FieldDescriptor::TYPE_ENUM : return "Enum" ; - case FieldDescriptor::TYPE_GROUP : return "Group" ; - case FieldDescriptor::TYPE_MESSAGE : return "Message" ; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -// For encodings with fixed sizes, returns that size in bytes. Otherwise -// returns -1. -int FixedSize(FieldDescriptor::Type type) { - switch (type) { - case FieldDescriptor::TYPE_INT32 : return -1; - case FieldDescriptor::TYPE_INT64 : return -1; - case FieldDescriptor::TYPE_UINT32 : return -1; - case FieldDescriptor::TYPE_UINT64 : return -1; - case FieldDescriptor::TYPE_SINT32 : return -1; - case FieldDescriptor::TYPE_SINT64 : return -1; - case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size; - case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size; - case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size; - case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size; - case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize; - case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize; - - case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize; - case FieldDescriptor::TYPE_ENUM : return -1; - - case FieldDescriptor::TYPE_STRING : return -1; - case FieldDescriptor::TYPE_BYTES : return -1; - case FieldDescriptor::TYPE_GROUP : return -1; - case FieldDescriptor::TYPE_MESSAGE : return -1; - - // No default because we want the compiler to complain if any new - // types are added. - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return -1; -} - -// Return true if the type is a that has variable length -// for instance String's. -bool IsVariableLenType(JavaType type) { - switch (type) { - case JAVATYPE_INT : return false; - case JAVATYPE_LONG : return false; - case JAVATYPE_FLOAT : return false; - case JAVATYPE_DOUBLE : return false; - case JAVATYPE_BOOLEAN: return false; - case JAVATYPE_STRING : return true; - case JAVATYPE_BYTES : return true; - case JAVATYPE_ENUM : return false; - case JAVATYPE_MESSAGE: return true; - - // No default because we want the compiler to complain if any new - // JavaTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return false; -} - -bool IsStringUtf8Handling(const FieldDescriptor* descriptor, - const Params params) { - return ((params.optimization() == JAVAMICRO_OPT_SPEED) - && (GetJavaType(descriptor) == JAVATYPE_STRING)); -} - -void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params, - map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - if (IsStringUtf8Handling(descriptor, params)) { - (*variables)["type"] = "com.google.protobuf.micro.StringUtf8Micro"; - string defaultValue = DefaultValue(params, descriptor); - if (defaultValue == "\"\"") { - (*variables)["default"] = - "com.google.protobuf.micro.StringUtf8Micro.EMPTY"; - } else { - (*variables)["default"] = "new com.google.protobuf.micro.StringUtf8Micro(" - + defaultValue + ")"; - } - } else { - (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); - (*variables)["default"] = DefaultValue(params, descriptor); - } - (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); - (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); - (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); - (*variables)["tag_size"] = SimpleItoa( - WireFormat::TagSize(descriptor->number(), descriptor->type())); - if (IsReferenceType(GetJavaType(descriptor))) { - (*variables)["null_check"] = - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n"; - } else { - (*variables)["null_check"] = ""; - } - int fixed_size = FixedSize(descriptor->type()); - if (fixed_size != -1) { - (*variables)["fixed_size"] = SimpleItoa(fixed_size); - } - (*variables)["message_name"] = descriptor->containing_type()->name(); -} -} // namespace - -// =================================================================== - -PrimitiveFieldGenerator:: -PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params) - : FieldGenerator(params), descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, params, &variables_); -} - -PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} - -void PrimitiveFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private boolean has$capitalized_name$;\n" - "private $type$ $name$_ = $default$;\n" - "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"); - if (IsStringUtf8Handling(descriptor_, params_)) { - printer->Print(variables_, - "public String get$capitalized_name$() { return $name$_.getString(); }\n" - "public $type$ get$capitalized_name$StringUtf8() { return $name$_; }\n" - "public $message_name$ set$capitalized_name$(String value) {\n" - " has$capitalized_name$ = true;\n" - " if ($name$_ == $default$) {\n" - " $name$_ = new $type$(value);\n" - " } else {\n" - " $name$_.setString(value);\n" - " }\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " has$capitalized_name$ = false;\n" - " $name$_ = $default$;\n" - " return this;\n" - "}\n"); - } else { - printer->Print(variables_, - "public $type$ get$capitalized_name$() { return $name$_; }\n"); - if (IsVariableLenType(GetJavaType(descriptor_))) { - printer->Print(variables_, - "public $message_name$ set$capitalized_name$($type$ value) {\n" - " has$capitalized_name$ = true;\n" - " $name$_ = value;\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " has$capitalized_name$ = false;\n" - " $name$_ = $default$;\n" - " return this;\n" - "}\n"); - } else { - printer->Print(variables_, - "public $message_name$ set$capitalized_name$($type$ value) {\n" - " has$capitalized_name$ = true;\n" - " $name$_ = value;\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " has$capitalized_name$ = false;\n" - " $name$_ = $default$;\n" - " return this;\n" - "}\n"); - } - } -} - -void PrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.has$capitalized_name$()) {\n" - " set$capitalized_name$(other.get$capitalized_name$());\n" - "}\n"); -} - -void PrimitiveFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "set$capitalized_name$(input.read$capitalized_type$());\n"); -} - -void PrimitiveFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - if (IsStringUtf8Handling(descriptor_, params_)) { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.writeStringUtf8($number$, get$capitalized_name$StringUtf8());\n" - "}\n"); - } else { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.write$capitalized_type$($number$, get$capitalized_name$());\n" - "}\n"); - } -} - -void PrimitiveFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - if (IsStringUtf8Handling(descriptor_, params_)) { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .computeStringUtf8Size($number$, get$capitalized_name$StringUtf8());\n" - "}\n"); - } else { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .compute$capitalized_type$Size($number$, get$capitalized_name$());\n" - "}\n"); - } -} - -string PrimitiveFieldGenerator::GetBoxedType() const { - return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); -} - -// =================================================================== - -RepeatedPrimitiveFieldGenerator:: -RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params) - : FieldGenerator(params), descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, params, &variables_); - if (descriptor_->options().packed()) { - GOOGLE_LOG(FATAL) << "MicroRuntime does not support packed"; - } -} - -RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} - -void RepeatedPrimitiveFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - if (IsStringUtf8Handling(descriptor_, params_)) { - if (params_.java_use_vector()) { - printer->Print(variables_, - "private java.util.Vector $name$_ = new java.util.Vector();\n" - "public java.util.Vector get$capitalized_name$List() {\n" - " return $name$_;\n" - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public String get$capitalized_name$(int index) {\n" - " return (($type$)$name$_.elementAt(index)).getString();\n" - "}\n" - "public $type$ get$capitalized_name$StringUtf8(int index) {\n" - " return ($type$)$name$_.elementAt(index);\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, String value) {\n" - "$null_check$" - " $name$_.setElementAt(new $type$(value), index);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$(String value) {\n" - "$null_check$" - " $name$_.addElement(new $type$(value));\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_.removeAllElements();\n" - " return this;\n" - "}\n"); - } else { - printer->Print(variables_, - "private java.util.List<$type$> $name$_ =\n" - " java.util.Collections.emptyList();\n" - "public java.util.List<$type$> get$capitalized_name$List() {\n" - " return $name$_;\n" // note: unmodifiable list - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public String get$capitalized_name$(int index) {\n" - " return $name$_.get(index).getString();\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, String value) {\n" - "$null_check$" - " $name$_.set(index, new $type$(value));\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$(String value) {\n" - "$null_check$" - " if ($name$_.isEmpty()) {\n" - " $name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " $name$_.add(new $type$(value));\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); - } - } else if (params_.java_use_vector()) { - if (IsReferenceType(GetJavaType(descriptor_))) { - printer->Print(variables_, - "private java.util.Vector $name$_ = new java.util.Vector();\n" - "public java.util.Vector get$capitalized_name$List() {\n" - " return $name$_;\n" - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return ($type$) $name$_.elementAt(index);\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" - "$null_check$" - " $name$_.setElementAt(value, index);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$($type$ value) {\n" - "$null_check$" - " $name$_.addElement(value);\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_.removeAllElements();\n" - " return this;\n" - "}\n"); - } else { - printer->Print(variables_, - "private java.util.Vector $name$_ = new java.util.Vector();\n" - "public java.util.Vector get$capitalized_name$List() {\n" - " return $name$_;\n" - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return (($boxed_type$)$name$_.elementAt(index)).$type$Value();\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" - "$null_check$" - " $name$_.setElementAt(new $boxed_type$(value), index);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$($type$ value) {\n" - "$null_check$" - " $name$_.addElement(new $boxed_type$(value));\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_.removeAllElements();\n" - " return this;\n" - "}\n"); - } - } else { - printer->Print(variables_, - "private java.util.List<$boxed_type$> $name$_ =\n" - " java.util.Collections.emptyList();\n" - "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n" - " return $name$_;\n" // note: unmodifiable list - "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return $name$_.get(index);\n" - "}\n" - "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" - "$null_check$" - " $name$_.set(index, value);\n" - " return this;\n" - "}\n" - "public $message_name$ add$capitalized_name$($type$ value) {\n" - "$null_check$" - " if ($name$_.isEmpty()) {\n" - " $name$_ = new java.util.ArrayList<$boxed_type$>();\n" - " }\n" - " $name$_.add(value);\n" - " return this;\n" - "}\n" - "public $message_name$ clear$capitalized_name$() {\n" - " $name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); - } - if (descriptor_->options().packed()) { - printer->Print(variables_, - "private int $name$MemoizedSerializedSize;\n"); - } -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - if (params_.java_use_vector()) { - printer->Print(variables_, - "if (other.$name$_.size() != 0) {\n" - " for (int i = 0; i < other.$name$_.size(); i++)) {\n" - " result.$name$_.addElement(other.$name$_.elementAt(i));\n" - " }\n" - "}\n"); - } else { - printer->Print(variables_, - "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.addAll(other.$name$_);\n" - "}\n"); - } -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { - printer->Print(variables_, - "int length = input.readRawVarint32();\n" - "int limit = input.pushLimit(length);\n" - "while (input.getBytesUntilLimit() > 0) {\n" - " add$capitalized_name$(input.read$capitalized_type$());\n" - "}\n" - "input.popLimit(limit);\n"); - } else { - printer->Print(variables_, - "add$capitalized_name$(input.read$capitalized_type$());\n"); - } -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { - printer->Print(variables_, - "if (get$capitalized_name$List().size() > 0) {\n" - " output.writeRawVarint32($tag$);\n" - " output.writeRawVarint32($name$MemoizedSerializedSize);\n" - "}\n"); - if (params_.java_use_vector()) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " output.write$capitalized_type$NoTag(get$capitalized_name$(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.write$capitalized_type$NoTag(element);\n" - "}\n"); - } - } else { - if (params_.java_use_vector()) { - if (IsStringUtf8Handling(descriptor_, params_)) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " output.writeStringUtf8($number$, get$capitalized_name$StringUtf8(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " output.write$capitalized_type$($number$, get$capitalized_name$(i));\n" - "}\n"); - } - } else { - if (IsStringUtf8Handling(descriptor_, params_)) { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.writeStringUtf8($number$, element);\n" - "}\n"); - } else { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.write$capitalized_type$($number$, element);\n" - "}\n"); - } - } - } -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "{\n" - " int dataSize = 0;\n"); - printer->Indent(); - - if (FixedSize(descriptor_->type()) == -1) { - if (params_.java_use_vector()) { - printer->Print(variables_, - "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" - " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"); - if (IsStringUtf8Handling(descriptor_, params_)) { - printer->Print(variables_, - " .computeStringUtf8SizeNoTag(get$capitalized_name$StringUtf8(i));\n" - "}\n"); - } else { - printer->Print(variables_, - " .compute$capitalized_type$SizeNoTag(($type$)get$capitalized_name$(i));\n" - "}\n"); - } - } else { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"); - if (IsStringUtf8Handling(descriptor_, params_)) { - printer->Print(variables_, - " .computeStringUtf8SizeNoTag(element);\n" - "}\n"); - } else { - printer->Print(variables_, - " .compute$capitalized_type$SizeNoTag(element);\n" - "}\n"); - } - } - } else { - printer->Print(variables_, - "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n"); - } - - printer->Print( - "size += dataSize;\n"); - - if (descriptor_->options().packed()) { - if (params_.java_use_vector()) { - printer->Print(variables_, - "if (get$capitalized_name$List().size() != 0) {\n"); - } else { - printer->Print(variables_, - "if (!get$capitalized_name$List().isEmpty()) {\n"); - } - printer->Print(variables_, - " size += $tag_size$;\n" - " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" - " .computeInt32SizeNoTag(dataSize);\n" - "}\n"); - } else { - printer->Print(variables_, - "size += $tag_size$ * get$capitalized_name$List().size();\n"); - } - - // cache the data size for packed fields. - if (descriptor_->options().packed()) { - printer->Print(variables_, - "$name$MemoizedSerializedSize = dataSize;\n"); - } - - printer->Outdent(); - printer->Print("}\n"); -} - -string RepeatedPrimitiveFieldGenerator::GetBoxedType() const { - return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); -} - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h deleted file mode 100644 index 88d8eec..0000000 --- a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h +++ /dev/null @@ -1,94 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/javamicro/javamicro_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace javamicro { - -class PrimitiveFieldGenerator : public FieldGenerator { - public: - explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params ¶ms); - ~PrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); -}; - -class RepeatedPrimitiveFieldGenerator : public FieldGenerator { - public: - explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params); - ~RepeatedPrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); -}; - -} // namespace javamicro -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__ diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index 41dc5b9..d9b0c3f 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -34,12 +34,12 @@ #include <google/protobuf/compiler/cpp/cpp_generator.h> #include <google/protobuf/compiler/python/python_generator.h> #include <google/protobuf/compiler/java/java_generator.h> -#include <google/protobuf/compiler/javamicro/javamicro_generator.h> int main(int argc, char* argv[]) { google::protobuf::compiler::CommandLineInterface cli; + cli.AllowPlugins("protoc-"); // Proto2 C++ google::protobuf::compiler::cpp::CppGenerator cpp_generator; @@ -57,10 +57,5 @@ int main(int argc, char* argv[]) { cli.RegisterGenerator("--python_out", &py_generator, "Generate Python source file."); - // Proto2 JavaMicro - google::protobuf::compiler::javamicro::JavaMicroGenerator javamicro_generator; - cli.RegisterGenerator("--javamicro_out", &javamicro_generator, - "Generate Java source file micro runtime."); - return cli.Run(argc, argv); } diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc new file mode 100644 index 0000000..83d5a4e --- /dev/null +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -0,0 +1,209 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include <google/protobuf/compiler/mock_code_generator.h> + +#include <google/protobuf/testing/file.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> +#include <gtest/gtest.h> +#include <google/protobuf/stubs/stl_util-inl.h> + +namespace google { +namespace protobuf { +namespace compiler { + +static const char* kFirstInsertionPointName = "first_mock_insertion_point"; +static const char* kSecondInsertionPointName = "second_mock_insertion_point"; +static const char* kFirstInsertionPoint = + "# @@protoc_insertion_point(first_mock_insertion_point) is here\n"; +static const char* kSecondInsertionPoint = + " # @@protoc_insertion_point(second_mock_insertion_point) is here\n"; + +MockCodeGenerator::MockCodeGenerator(const string& name) + : name_(name) {} + +MockCodeGenerator::~MockCodeGenerator() {} + +void MockCodeGenerator::ExpectGenerated( + const string& name, + const string& parameter, + const string& insertions, + const string& file, + const string& first_message_name, + const string& output_directory) { + string content; + ASSERT_TRUE(File::ReadFileToString( + output_directory + "/" + GetOutputFileName(name, file), &content)); + + vector<string> lines; + SplitStringUsing(content, "\n", &lines); + + while (!lines.empty() && lines.back().empty()) { + lines.pop_back(); + } + for (int i = 0; i < lines.size(); i++) { + lines[i] += "\n"; + } + + vector<string> insertion_list; + if (!insertions.empty()) { + SplitStringUsing(insertions, ",", &insertion_list); + } + + ASSERT_EQ(lines.size(), 3 + insertion_list.size() * 2); + EXPECT_EQ(GetOutputFileContent(name, parameter, file, first_message_name), + lines[0]); + + EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]); + EXPECT_EQ(kSecondInsertionPoint, lines[2 + insertion_list.size() * 2]); + + for (int i = 0; i < insertion_list.size(); i++) { + EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert", + file, first_message_name), + lines[1 + i]); + // Second insertion point is indented, so the inserted text should + // automatically be indented too. + EXPECT_EQ(" " + GetOutputFileContent(insertion_list[i], "second_insert", + file, first_message_name), + lines[2 + insertion_list.size() + i]); + } +} + +bool MockCodeGenerator::Generate( + const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const { + for (int i = 0; i < file->message_type_count(); i++) { + if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) { + string command = StripPrefixString(file->message_type(i)->name(), + "MockCodeGenerator_"); + if (command == "Error") { + *error = "Saw message type MockCodeGenerator_Error."; + return false; + } else if (command == "Exit") { + cerr << "Saw message type MockCodeGenerator_Exit." << endl; + exit(123); + } else if (command == "Abort") { + cerr << "Saw message type MockCodeGenerator_Abort." << endl; + abort(); + } else { + GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command; + } + } + } + + if (HasPrefixString(parameter, "insert=")) { + vector<string> insert_into; + SplitStringUsing(StripPrefixString(parameter, "insert="), + ",", &insert_into); + + for (int i = 0; i < insert_into.size(); i++) { + { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->OpenForInsert( + GetOutputFileName(insert_into[i], file), + kFirstInsertionPointName)); + io::Printer printer(output.get(), '$'); + printer.PrintRaw(GetOutputFileContent(name_, "first_insert", file)); + if (printer.failed()) { + *error = "MockCodeGenerator detected write error."; + return false; + } + } + + { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->OpenForInsert( + GetOutputFileName(insert_into[i], file), + kSecondInsertionPointName)); + io::Printer printer(output.get(), '$'); + printer.PrintRaw(GetOutputFileContent(name_, "second_insert", file)); + if (printer.failed()) { + *error = "MockCodeGenerator detected write error."; + return false; + } + } + } + } else { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->Open(GetOutputFileName(name_, file))); + + io::Printer printer(output.get(), '$'); + printer.PrintRaw(GetOutputFileContent(name_, parameter, file)); + printer.PrintRaw(kFirstInsertionPoint); + printer.PrintRaw(kSecondInsertionPoint); + + if (printer.failed()) { + *error = "MockCodeGenerator detected write error."; + return false; + } + } + + return true; +} + +string MockCodeGenerator::GetOutputFileName(const string& generator_name, + const FileDescriptor* file) { + return GetOutputFileName(generator_name, file->name()); +} + +string MockCodeGenerator::GetOutputFileName(const string& generator_name, + const string& file) { + return file + ".MockCodeGenerator." + generator_name; +} + +string MockCodeGenerator::GetOutputFileContent(const string& generator_name, + const string& parameter, + const FileDescriptor* file) { + return GetOutputFileContent( + generator_name, parameter, file->name(), + file->message_type_count() > 0 ? + file->message_type(0)->name() : "(none)"); +} + +string MockCodeGenerator::GetOutputFileContent( + const string& generator_name, + const string& parameter, + const string& file, + const string& first_message_name) { + return strings::Substitute("$0: $1, $2, $3\n", + generator_name, parameter, file, first_message_name); +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h new file mode 100644 index 0000000..01d69dd --- /dev/null +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -0,0 +1,108 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#ifndef GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__ + +#include <string> +#include <google/protobuf/compiler/code_generator.h> + +namespace google { +namespace protobuf { +namespace compiler { + +// A mock CodeGenerator, used by command_line_interface_unittest. This is in +// its own file so that it can be used both directly and as a plugin. +// +// Generate() produces some output which can be checked by ExpectCalled(). The +// generator can run in a different process (e.g. a plugin). +// +// If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines +// into the files generated by other MockCodeGenerators instead of creating +// its own file. NAMES is a comma-separated list of the names of those other +// MockCodeGenerators. +// +// MockCodeGenerator will also modify its behavior slightly if the input file +// contains a message type with one of the following names: +// MockCodeGenerator_Error: Causes Generate() to return false and set the +// error message to "Saw message type MockCodeGenerator_Error." +// MockCodeGenerator_Exit: Generate() prints "Saw message type +// MockCodeGenerator_Exit." to stderr and then calls exit(123). +// MockCodeGenerator_Abort: Generate() prints "Saw message type +// MockCodeGenerator_Abort." to stderr and then calls abort(). +class MockCodeGenerator : public CodeGenerator { + public: + MockCodeGenerator(const string& name); + virtual ~MockCodeGenerator(); + + // Expect (via gTest) that a MockCodeGenerator with the given name was called + // with the given parameters by inspecting the output location. + // + // |insertions| is a comma-separated list of names of MockCodeGenerators which + // should have inserted lines into this file. + static void ExpectGenerated(const string& name, + const string& parameter, + const string& insertions, + const string& file, + const string& first_message_name, + const string& output_directory); + + // Get the name of the file which would be written by the given generator. + static string GetOutputFileName(const string& generator_name, + const FileDescriptor* file); + static string GetOutputFileName(const string& generator_name, + const string& file); + + // implements CodeGenerator ---------------------------------------- + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const; + + private: + string name_; + + static string GetOutputFileContent(const string& generator_name, + const string& parameter, + const FileDescriptor* file); + static string GetOutputFileContent(const string& generator_name, + const string& parameter, + const string& file, + const string& first_message_name); +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 02304d6..758f70d 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -34,8 +34,9 @@ // // Recursive descent FTW. -#include <google/protobuf/stubs/hash.h> #include <float.h> +#include <google/protobuf/stubs/hash.h> +#include <limits> #include <google/protobuf/compiler/parser.h> @@ -206,6 +207,14 @@ bool Parser::ConsumeNumber(double* output, const char* error) { *output = value; input_->Next(); return true; + } else if (LookingAt("inf")) { + *output = numeric_limits<double>::infinity(); + input_->Next(); + return true; + } else if (LookingAt("nan")) { + *output = numeric_limits<double>::quiet_NaN(); + input_->Next(); + return true; } else { AddError(error); return false; diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index c4f08e7..e2262b8 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -336,6 +336,9 @@ TEST_F(ParseMessageTest, FieldDefaults) { " required double foo = 1 [default= 10.5];\n" " required double foo = 1 [default=-11.5];\n" " required double foo = 1 [default= 12 ];\n" + " required double foo = 1 [default= inf ];\n" + " required double foo = 1 [default=-inf ];\n" + " required double foo = 1 [default= nan ];\n" " required string foo = 1 [default='13\\001'];\n" " required string foo = 1 [default='a' \"b\" \n \"c\"];\n" " required bytes foo = 1 [default='14\\002'];\n" @@ -367,6 +370,9 @@ TEST_F(ParseMessageTest, FieldDefaults) { " field { type:TYPE_DOUBLE default_value:\"10.5\" "ETC" }" " field { type:TYPE_DOUBLE default_value:\"-11.5\" "ETC" }" " field { type:TYPE_DOUBLE default_value:\"12\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"inf\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"-inf\" "ETC" }" + " field { type:TYPE_DOUBLE default_value:\"nan\" "ETC" }" " field { type:TYPE_STRING default_value:\"13\\001\" "ETC" }" " field { type:TYPE_STRING default_value:\"abc\" "ETC" }" " field { type:TYPE_BYTES default_value:\"14\\\\002\" "ETC" }" diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc new file mode 100644 index 0000000..a4aedaf --- /dev/null +++ b/src/google/protobuf/compiler/plugin.cc @@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include <google/protobuf/compiler/plugin.h> + +#include <iostream> +#include <set> + +#ifdef _WIN32 +#include <io.h> +#include <fcntl.h> +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif +#else +#include <unistd.h> +#endif + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/plugin.pb.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> + + +namespace google { +namespace protobuf { +namespace compiler { + +class GeneratorResponseOutputDirectory : public OutputDirectory { + public: + GeneratorResponseOutputDirectory(CodeGeneratorResponse* response) + : response_(response) {} + virtual ~GeneratorResponseOutputDirectory() {} + + // implements OutputDirectory -------------------------------------- + + virtual io::ZeroCopyOutputStream* Open(const string& filename) { + CodeGeneratorResponse::File* file = response_->add_file(); + file->set_name(filename); + return new io::StringOutputStream(file->mutable_content()); + } + + virtual io::ZeroCopyOutputStream* OpenForInsert( + const string& filename, const string& insertion_point) { + CodeGeneratorResponse::File* file = response_->add_file(); + file->set_name(filename); + file->set_insertion_point(insertion_point); + return new io::StringOutputStream(file->mutable_content()); + } + + private: + CodeGeneratorResponse* response_; +}; + +int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { + + if (argc > 1) { + cerr << argv[0] << ": Unknown option: " << argv[1] << endl; + return 1; + } + +#ifdef _WIN32 + _setmode(STDIN_FILENO, _O_BINARY); + _setmode(STDOUT_FILENO, _O_BINARY); +#endif + + CodeGeneratorRequest request; + if (!request.ParseFromFileDescriptor(STDIN_FILENO)) { + cerr << argv[0] << ": protoc sent unparseable request to plugin." << endl; + return 1; + } + + DescriptorPool pool; + for (int i = 0; i < request.proto_file_size(); i++) { + const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); + if (file == NULL) { + // BuildFile() already wrote an error message. + return 1; + } + } + + CodeGeneratorResponse response; + GeneratorResponseOutputDirectory output_directory(&response); + + for (int i = 0; i < request.file_to_generate_size(); i++) { + const FileDescriptor* file = + pool.FindFileByName(request.file_to_generate(i)); + if (file == NULL) { + cerr << argv[0] << ": protoc asked plugin to generate a file but " + "did not provide a descriptor for the file: " + << request.file_to_generate(i) << endl; + return 1; + } + + string error; + bool succeeded = generator->Generate( + file, request.parameter(), &output_directory, &error); + + if (!succeeded && error.empty()) { + error = "Code generator returned false but provided no error " + "description."; + } + if (!error.empty()) { + response.set_error(file->name() + ": " + error); + break; + } + } + + if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) { + cerr << argv[0] << ": Error writing to stdout." << endl; + return 1; + } + + return 0; +} + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_generator.h b/src/google/protobuf/compiler/plugin.h index a1c33b7..7c40333 100644 --- a/src/google/protobuf/compiler/javamicro/javamicro_generator.h +++ b/src/google/protobuf/compiler/plugin.h @@ -29,44 +29,45 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. // -// Generates Java micro code for a given .proto file. +// Front-end for protoc code generator plugins written in C++. +// +// To implement a protoc plugin in C++, simply write an implementation of +// CodeGenerator, then create a main() function like: +// int main(int argc, char* argv[]) { +// MyCodeGenerator generator; +// return google::protobuf::compiler::PluginMain(argc, argv, &generator); +// } +// You must link your plugin against libprotobuf and libprotoc. +// +// To get protoc to use the plugin, do one of the following: +// * Place the plugin binary somewhere in the PATH and give it the name +// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you +// then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace +// "NAME" with your plugin's name), protoc will invoke your plugin to generate +// the output, which will be placed in OUT_DIR. +// * Place the plugin binary anywhere, with any name, and pass the --plugin +// parameter to protoc to direct it to your plugin like so: +// protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR +// On Windows, make sure to include the .exe suffix: +// protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__ +#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ +#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ -#include <string> -#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/stubs/common.h> namespace google { namespace protobuf { namespace compiler { -namespace javamicro { - -// CodeGenerator implementation which generates Java micro code. If you create your -// own protocol compiler binary and you want it to support Java output for the -// micro runtime, you can do so by registering an instance of this CodeGenerator with -// the CommandLineInterface in your main() function. -class LIBPROTOC_EXPORT JavaMicroGenerator : public CodeGenerator { - public: - JavaMicroGenerator(); - ~JavaMicroGenerator(); - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const; +class CodeGenerator; // code_generator.h - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaMicroGenerator); -}; +// Implements main() for a protoc plugin exposing the given code generator. +LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator); -} // namespace javamicro } // namespace compiler } // namespace protobuf } // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__ +#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc new file mode 100644 index 0000000..6b0dd55 --- /dev/null +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -0,0 +1,1084 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/compiler/plugin.pb.h" +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { +namespace compiler { + +namespace { + +const ::google::protobuf::Descriptor* CodeGeneratorRequest_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + CodeGeneratorRequest_reflection_ = NULL; +const ::google::protobuf::Descriptor* CodeGeneratorResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + CodeGeneratorResponse_reflection_ = NULL; +const ::google::protobuf::Descriptor* CodeGeneratorResponse_File_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + CodeGeneratorResponse_File_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/compiler/plugin.proto"); + GOOGLE_CHECK(file != NULL); + CodeGeneratorRequest_descriptor_ = file->message_type(0); + static const int CodeGeneratorRequest_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_), + }; + CodeGeneratorRequest_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + CodeGeneratorRequest_descriptor_, + CodeGeneratorRequest::default_instance_, + CodeGeneratorRequest_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(CodeGeneratorRequest)); + CodeGeneratorResponse_descriptor_ = file->message_type(1); + static const int CodeGeneratorResponse_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_), + }; + CodeGeneratorResponse_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + CodeGeneratorResponse_descriptor_, + CodeGeneratorResponse::default_instance_, + CodeGeneratorResponse_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(CodeGeneratorResponse)); + CodeGeneratorResponse_File_descriptor_ = CodeGeneratorResponse_descriptor_->nested_type(0); + static const int CodeGeneratorResponse_File_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, insertion_point_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_), + }; + CodeGeneratorResponse_File_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + CodeGeneratorResponse_File_descriptor_, + CodeGeneratorResponse_File::default_instance_, + CodeGeneratorResponse_File_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(CodeGeneratorResponse_File)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + CodeGeneratorRequest_descriptor_, &CodeGeneratorRequest::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + CodeGeneratorResponse_descriptor_, &CodeGeneratorResponse::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + CodeGeneratorResponse_File_descriptor_, &CodeGeneratorResponse_File::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + delete CodeGeneratorRequest::default_instance_; + delete CodeGeneratorRequest_reflection_; + delete CodeGeneratorResponse::default_instance_; + delete CodeGeneratorResponse_reflection_; + delete CodeGeneratorResponse_File::default_instance_; + delete CodeGeneratorResponse_File_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n%google/protobuf/compiler/plugin.proto\022" + "\030google.protobuf.compiler\032 google/protob" + "uf/descriptor.proto\"}\n\024CodeGeneratorRequ" + "est\022\030\n\020file_to_generate\030\001 \003(\t\022\021\n\tparamet" + "er\030\002 \001(\t\0228\n\nproto_file\030\017 \003(\0132$.google.pr" + "otobuf.FileDescriptorProto\"\252\001\n\025CodeGener" + "atorResponse\022\r\n\005error\030\001 \001(\t\022B\n\004file\030\017 \003(" + "\01324.google.protobuf.compiler.CodeGenerat" + "orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n" + "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\t", 399); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes); + CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest(); + CodeGeneratorResponse::default_instance_ = new CodeGeneratorResponse(); + CodeGeneratorResponse_File::default_instance_ = new CodeGeneratorResponse_File(); + CodeGeneratorRequest::default_instance_->InitAsDefaultInstance(); + CodeGeneratorResponse::default_instance_->InitAsDefaultInstance(); + CodeGeneratorResponse_File::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_; + + +// =================================================================== + +const ::std::string CodeGeneratorRequest::_default_parameter_; +#ifndef _MSC_VER +const int CodeGeneratorRequest::kFileToGenerateFieldNumber; +const int CodeGeneratorRequest::kParameterFieldNumber; +const int CodeGeneratorRequest::kProtoFileFieldNumber; +#endif // !_MSC_VER + +CodeGeneratorRequest::CodeGeneratorRequest() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void CodeGeneratorRequest::InitAsDefaultInstance() { +} + +CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void CodeGeneratorRequest::SharedCtor() { + _cached_size_ = 0; + parameter_ = const_cast< ::std::string*>(&_default_parameter_); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CodeGeneratorRequest::~CodeGeneratorRequest() { + SharedDtor(); +} + +void CodeGeneratorRequest::SharedDtor() { + if (parameter_ != &_default_parameter_) { + delete parameter_; + } + if (this != default_instance_) { + } +} + +void CodeGeneratorRequest::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() { + protobuf_AssignDescriptorsOnce(); + return CodeGeneratorRequest_descriptor_; +} + +const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_; +} + +CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL; + +CodeGeneratorRequest* CodeGeneratorRequest::New() const { + return new CodeGeneratorRequest; +} + +void CodeGeneratorRequest::Clear() { + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (_has_bit(1)) { + if (parameter_ != &_default_parameter_) { + parameter_->clear(); + } + } + } + file_to_generate_.Clear(); + proto_file_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool CodeGeneratorRequest::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string file_to_generate = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file_to_generate: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_file_to_generate())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_to_generate(0).data(), this->file_to_generate(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_file_to_generate; + if (input->ExpectTag(18)) goto parse_parameter; + break; + } + + // optional string parameter = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_parameter: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_parameter())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->parameter().data(), this->parameter().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_proto_file; + break; + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + case 15: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_proto_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_proto_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_proto_file; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void CodeGeneratorRequest::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string file_to_generate = 1; + for (int i = 0; i < this->file_to_generate_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_to_generate(i).data(), this->file_to_generate(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->file_to_generate(i), output); + } + + // optional string parameter = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->parameter().data(), this->parameter().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->parameter(), output); + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + for (int i = 0; i < this->proto_file_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 15, this->proto_file(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* CodeGeneratorRequest::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string file_to_generate = 1; + for (int i = 0; i < this->file_to_generate_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->file_to_generate(i).data(), this->file_to_generate(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->file_to_generate(i), target); + } + + // optional string parameter = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->parameter().data(), this->parameter().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->parameter(), target); + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + for (int i = 0; i < this->proto_file_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 15, this->proto_file(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int CodeGeneratorRequest::ByteSize() const { + int total_size = 0; + + if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { + // optional string parameter = 2; + if (has_parameter()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->parameter()); + } + + } + // repeated string file_to_generate = 1; + total_size += 1 * this->file_to_generate_size(); + for (int i = 0; i < this->file_to_generate_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_to_generate(i)); + } + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + total_size += 1 * this->proto_file_size(); + for (int i = 0; i < this->proto_file_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->proto_file(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const CodeGeneratorRequest* source = + ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorRequest*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) { + GOOGLE_CHECK_NE(&from, this); + file_to_generate_.MergeFrom(from.file_to_generate_); + proto_file_.MergeFrom(from.proto_file_); + if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { + if (from._has_bit(1)) { + set_parameter(from.parameter()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void CodeGeneratorRequest::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CodeGeneratorRequest::IsInitialized() const { + + for (int i = 0; i < proto_file_size(); i++) { + if (!this->proto_file(i).IsInitialized()) return false; + } + return true; +} + +void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) { + if (other != this) { + file_to_generate_.Swap(&other->file_to_generate_); + std::swap(parameter_, other->parameter_); + proto_file_.Swap(&other->proto_file_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = CodeGeneratorRequest_descriptor_; + metadata.reflection = CodeGeneratorRequest_reflection_; + return metadata; +} + + +// =================================================================== + +const ::std::string CodeGeneratorResponse_File::_default_name_; +const ::std::string CodeGeneratorResponse_File::_default_insertion_point_; +const ::std::string CodeGeneratorResponse_File::_default_content_; +#ifndef _MSC_VER +const int CodeGeneratorResponse_File::kNameFieldNumber; +const int CodeGeneratorResponse_File::kInsertionPointFieldNumber; +const int CodeGeneratorResponse_File::kContentFieldNumber; +#endif // !_MSC_VER + +CodeGeneratorResponse_File::CodeGeneratorResponse_File() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void CodeGeneratorResponse_File::InitAsDefaultInstance() { +} + +CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void CodeGeneratorResponse_File::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&_default_name_); + insertion_point_ = const_cast< ::std::string*>(&_default_insertion_point_); + content_ = const_cast< ::std::string*>(&_default_content_); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { + SharedDtor(); +} + +void CodeGeneratorResponse_File::SharedDtor() { + if (name_ != &_default_name_) { + delete name_; + } + if (insertion_point_ != &_default_insertion_point_) { + delete insertion_point_; + } + if (content_ != &_default_content_) { + delete content_; + } + if (this != default_instance_) { + } +} + +void CodeGeneratorResponse_File::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() { + protobuf_AssignDescriptorsOnce(); + return CodeGeneratorResponse_File_descriptor_; +} + +const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_; +} + +CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL; + +CodeGeneratorResponse_File* CodeGeneratorResponse_File::New() const { + return new CodeGeneratorResponse_File; +} + +void CodeGeneratorResponse_File::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (_has_bit(0)) { + if (name_ != &_default_name_) { + name_->clear(); + } + } + if (_has_bit(1)) { + if (insertion_point_ != &_default_insertion_point_) { + insertion_point_->clear(); + } + } + if (_has_bit(2)) { + if (content_ != &_default_content_) { + content_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool CodeGeneratorResponse_File::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_insertion_point; + break; + } + + // optional string insertion_point = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_insertion_point: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_insertion_point())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->insertion_point().data(), this->insertion_point().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_content; + break; + } + + // optional string content = 15; + case 15: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_content: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_content())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->content().data(), this->content().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void CodeGeneratorResponse_File::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string name = 1; + if (_has_bit(0)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // optional string insertion_point = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->insertion_point().data(), this->insertion_point().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->insertion_point(), output); + } + + // optional string content = 15; + if (_has_bit(2)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->content().data(), this->content().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 15, this->content(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string name = 1; + if (_has_bit(0)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional string insertion_point = 2; + if (_has_bit(1)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->insertion_point().data(), this->insertion_point().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->insertion_point(), target); + } + + // optional string content = 15; + if (_has_bit(2)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->content().data(), this->content().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 15, this->content(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int CodeGeneratorResponse_File::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string insertion_point = 2; + if (has_insertion_point()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->insertion_point()); + } + + // optional string content = 15; + if (has_content()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->content()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const CodeGeneratorResponse_File* source = + ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse_File*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from._has_bit(0)) { + set_name(from.name()); + } + if (from._has_bit(1)) { + set_insertion_point(from.insertion_point()); + } + if (from._has_bit(2)) { + set_content(from.content()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void CodeGeneratorResponse_File::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CodeGeneratorResponse_File::IsInitialized() const { + + return true; +} + +void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(insertion_point_, other->insertion_point_); + std::swap(content_, other->content_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = CodeGeneratorResponse_File_descriptor_; + metadata.reflection = CodeGeneratorResponse_File_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +const ::std::string CodeGeneratorResponse::_default_error_; +#ifndef _MSC_VER +const int CodeGeneratorResponse::kErrorFieldNumber; +const int CodeGeneratorResponse::kFileFieldNumber; +#endif // !_MSC_VER + +CodeGeneratorResponse::CodeGeneratorResponse() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void CodeGeneratorResponse::InitAsDefaultInstance() { +} + +CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void CodeGeneratorResponse::SharedCtor() { + _cached_size_ = 0; + error_ = const_cast< ::std::string*>(&_default_error_); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CodeGeneratorResponse::~CodeGeneratorResponse() { + SharedDtor(); +} + +void CodeGeneratorResponse::SharedDtor() { + if (error_ != &_default_error_) { + delete error_; + } + if (this != default_instance_) { + } +} + +void CodeGeneratorResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return CodeGeneratorResponse_descriptor_; +} + +const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_; +} + +CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL; + +CodeGeneratorResponse* CodeGeneratorResponse::New() const { + return new CodeGeneratorResponse; +} + +void CodeGeneratorResponse::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (_has_bit(0)) { + if (error_ != &_default_error_) { + error_->clear(); + } + } + } + file_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool CodeGeneratorResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string error = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_error())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error().data(), this->error().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_file; + break; + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + case 15: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(122)) goto parse_file; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void CodeGeneratorResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // optional string error = 1; + if (_has_bit(0)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error().data(), this->error().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->error(), output); + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + for (int i = 0; i < this->file_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 15, this->file(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // optional string error = 1; + if (_has_bit(0)) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->error().data(), this->error().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->error(), target); + } + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + for (int i = 0; i < this->file_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 15, this->file(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int CodeGeneratorResponse::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string error = 1; + if (has_error()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->error()); + } + + } + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + total_size += 1 * this->file_size(); + for (int i = 0; i < this->file_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const CodeGeneratorResponse* source = + ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) { + GOOGLE_CHECK_NE(&from, this); + file_.MergeFrom(from.file_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from._has_bit(0)) { + set_error(from.error()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void CodeGeneratorResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CodeGeneratorResponse::IsInitialized() const { + + return true; +} + +void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) { + if (other != this) { + std::swap(error_, other->error_); + file_.Swap(&other->file_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = CodeGeneratorResponse_descriptor_; + metadata.reflection = CodeGeneratorResponse_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace compiler +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h new file mode 100644 index 0000000..f8f8053 --- /dev/null +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -0,0 +1,727 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/compiler/plugin.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 2003000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/generated_message_reflection.h> +#include "google/protobuf/descriptor.pb.h" +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { +namespace compiler { + +// Internal implementation detail -- do not call these. +void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + +class CodeGeneratorRequest; +class CodeGeneratorResponse; +class CodeGeneratorResponse_File; + +// =================================================================== + +class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message { + public: + CodeGeneratorRequest(); + virtual ~CodeGeneratorRequest(); + + CodeGeneratorRequest(const CodeGeneratorRequest& from); + + inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorRequest& default_instance(); + + void Swap(CodeGeneratorRequest* other); + + // implements Message ---------------------------------------------- + + CodeGeneratorRequest* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorRequest& from); + void MergeFrom(const CodeGeneratorRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string file_to_generate = 1; + inline int file_to_generate_size() const; + inline void clear_file_to_generate(); + static const int kFileToGenerateFieldNumber = 1; + inline const ::std::string& file_to_generate(int index) const; + inline ::std::string* mutable_file_to_generate(int index); + inline void set_file_to_generate(int index, const ::std::string& value); + inline void set_file_to_generate(int index, const char* value); + inline void set_file_to_generate(int index, const char* value, size_t size); + inline ::std::string* add_file_to_generate(); + inline void add_file_to_generate(const ::std::string& value); + inline void add_file_to_generate(const char* value); + inline void add_file_to_generate(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate(); + + // optional string parameter = 2; + inline bool has_parameter() const; + inline void clear_parameter(); + static const int kParameterFieldNumber = 2; + inline const ::std::string& parameter() const; + inline void set_parameter(const ::std::string& value); + inline void set_parameter(const char* value); + inline void set_parameter(const char* value, size_t size); + inline ::std::string* mutable_parameter(); + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + inline int proto_file_size() const; + inline void clear_proto_file(); + static const int kProtoFileFieldNumber = 15; + inline const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; + inline ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index); + inline ::google::protobuf::FileDescriptorProto* add_proto_file(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + proto_file() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + mutable_proto_file(); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) + private: + ::google::protobuf::UnknownFieldSet _unknown_fields_; + mutable int _cached_size_; + + ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_; + ::std::string* parameter_; + static const ::std::string _default_parameter_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_; + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? + inline bool _has_bit(int index) const { + return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; + } + inline void _set_bit(int index) { + _has_bits_[index / 32] |= (1u << (index % 32)); + } + inline void _clear_bit(int index) { + _has_bits_[index / 32] &= ~(1u << (index % 32)); + } + + void InitAsDefaultInstance(); + static CodeGeneratorRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message { + public: + CodeGeneratorResponse_File(); + virtual ~CodeGeneratorResponse_File(); + + CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); + + inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorResponse_File& default_instance(); + + void Swap(CodeGeneratorResponse_File* other); + + // implements Message ---------------------------------------------- + + CodeGeneratorResponse_File* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorResponse_File& from); + void MergeFrom(const CodeGeneratorResponse_File& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + + // optional string insertion_point = 2; + inline bool has_insertion_point() const; + inline void clear_insertion_point(); + static const int kInsertionPointFieldNumber = 2; + inline const ::std::string& insertion_point() const; + inline void set_insertion_point(const ::std::string& value); + inline void set_insertion_point(const char* value); + inline void set_insertion_point(const char* value, size_t size); + inline ::std::string* mutable_insertion_point(); + + // optional string content = 15; + inline bool has_content() const; + inline void clear_content(); + static const int kContentFieldNumber = 15; + inline const ::std::string& content() const; + inline void set_content(const ::std::string& value); + inline void set_content(const char* value); + inline void set_content(const char* value, size_t size); + inline ::std::string* mutable_content(); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) + private: + ::google::protobuf::UnknownFieldSet _unknown_fields_; + mutable int _cached_size_; + + ::std::string* name_; + static const ::std::string _default_name_; + ::std::string* insertion_point_; + static const ::std::string _default_insertion_point_; + ::std::string* content_; + static const ::std::string _default_content_; + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? + inline bool _has_bit(int index) const { + return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; + } + inline void _set_bit(int index) { + _has_bits_[index / 32] |= (1u << (index % 32)); + } + inline void _clear_bit(int index) { + _has_bits_[index / 32] &= ~(1u << (index % 32)); + } + + void InitAsDefaultInstance(); + static CodeGeneratorResponse_File* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message { + public: + CodeGeneratorResponse(); + virtual ~CodeGeneratorResponse(); + + CodeGeneratorResponse(const CodeGeneratorResponse& from); + + inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorResponse& default_instance(); + + void Swap(CodeGeneratorResponse* other); + + // implements Message ---------------------------------------------- + + CodeGeneratorResponse* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorResponse& from); + void MergeFrom(const CodeGeneratorResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef CodeGeneratorResponse_File File; + + // accessors ------------------------------------------------------- + + // optional string error = 1; + inline bool has_error() const; + inline void clear_error(); + static const int kErrorFieldNumber = 1; + inline const ::std::string& error() const; + inline void set_error(const ::std::string& value); + inline void set_error(const char* value); + inline void set_error(const char* value, size_t size); + inline ::std::string* mutable_error(); + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + inline int file_size() const; + inline void clear_file(); + static const int kFileFieldNumber = 15; + inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const; + inline ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index); + inline ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& + file() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* + mutable_file(); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) + private: + ::google::protobuf::UnknownFieldSet _unknown_fields_; + mutable int _cached_size_; + + ::std::string* error_; + static const ::std::string _default_error_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? + inline bool _has_bit(int index) const { + return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; + } + inline void _set_bit(int index) { + _has_bits_[index / 32] |= (1u << (index % 32)); + } + inline void _clear_bit(int index) { + _has_bits_[index / 32] &= ~(1u << (index % 32)); + } + + void InitAsDefaultInstance(); + static CodeGeneratorResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// CodeGeneratorRequest + +// repeated string file_to_generate = 1; +inline int CodeGeneratorRequest::file_to_generate_size() const { + return file_to_generate_.size(); +} +inline void CodeGeneratorRequest::clear_file_to_generate() { + file_to_generate_.Clear(); +} +inline const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const { + return file_to_generate_.Get(index); +} +inline ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) { + return file_to_generate_.Mutable(index); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) { + file_to_generate_.Mutable(index)->assign(value); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { + file_to_generate_.Mutable(index)->assign(value); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) { + file_to_generate_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); +} +inline ::std::string* CodeGeneratorRequest::add_file_to_generate() { + return file_to_generate_.Add(); +} +inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) { + file_to_generate_.Add()->assign(value); +} +inline void CodeGeneratorRequest::add_file_to_generate(const char* value) { + file_to_generate_.Add()->assign(value); +} +inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) { + file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +CodeGeneratorRequest::file_to_generate() const { + return file_to_generate_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +CodeGeneratorRequest::mutable_file_to_generate() { + return &file_to_generate_; +} + +// optional string parameter = 2; +inline bool CodeGeneratorRequest::has_parameter() const { + return _has_bit(1); +} +inline void CodeGeneratorRequest::clear_parameter() { + if (parameter_ != &_default_parameter_) { + parameter_->clear(); + } + _clear_bit(1); +} +inline const ::std::string& CodeGeneratorRequest::parameter() const { + return *parameter_; +} +inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) { + _set_bit(1); + if (parameter_ == &_default_parameter_) { + parameter_ = new ::std::string; + } + parameter_->assign(value); +} +inline void CodeGeneratorRequest::set_parameter(const char* value) { + _set_bit(1); + if (parameter_ == &_default_parameter_) { + parameter_ = new ::std::string; + } + parameter_->assign(value); +} +inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) { + _set_bit(1); + if (parameter_ == &_default_parameter_) { + parameter_ = new ::std::string; + } + parameter_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* CodeGeneratorRequest::mutable_parameter() { + _set_bit(1); + if (parameter_ == &_default_parameter_) { + parameter_ = new ::std::string; + } + return parameter_; +} + +// repeated .google.protobuf.FileDescriptorProto proto_file = 15; +inline int CodeGeneratorRequest::proto_file_size() const { + return proto_file_.size(); +} +inline void CodeGeneratorRequest::clear_proto_file() { + proto_file_.Clear(); +} +inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const { + return proto_file_.Get(index); +} +inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) { + return proto_file_.Mutable(index); +} +inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() { + return proto_file_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +CodeGeneratorRequest::proto_file() const { + return proto_file_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +CodeGeneratorRequest::mutable_proto_file() { + return &proto_file_; +} + +// ------------------------------------------------------------------- + +// CodeGeneratorResponse_File + +// optional string name = 1; +inline bool CodeGeneratorResponse_File::has_name() const { + return _has_bit(0); +} +inline void CodeGeneratorResponse_File::clear_name() { + if (name_ != &_default_name_) { + name_->clear(); + } + _clear_bit(0); +} +inline const ::std::string& CodeGeneratorResponse_File::name() const { + return *name_; +} +inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) { + _set_bit(0); + if (name_ == &_default_name_) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void CodeGeneratorResponse_File::set_name(const char* value) { + _set_bit(0); + if (name_ == &_default_name_) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) { + _set_bit(0); + if (name_ == &_default_name_) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* CodeGeneratorResponse_File::mutable_name() { + _set_bit(0); + if (name_ == &_default_name_) { + name_ = new ::std::string; + } + return name_; +} + +// optional string insertion_point = 2; +inline bool CodeGeneratorResponse_File::has_insertion_point() const { + return _has_bit(1); +} +inline void CodeGeneratorResponse_File::clear_insertion_point() { + if (insertion_point_ != &_default_insertion_point_) { + insertion_point_->clear(); + } + _clear_bit(1); +} +inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const { + return *insertion_point_; +} +inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) { + _set_bit(1); + if (insertion_point_ == &_default_insertion_point_) { + insertion_point_ = new ::std::string; + } + insertion_point_->assign(value); +} +inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) { + _set_bit(1); + if (insertion_point_ == &_default_insertion_point_) { + insertion_point_ = new ::std::string; + } + insertion_point_->assign(value); +} +inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) { + _set_bit(1); + if (insertion_point_ == &_default_insertion_point_) { + insertion_point_ = new ::std::string; + } + insertion_point_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() { + _set_bit(1); + if (insertion_point_ == &_default_insertion_point_) { + insertion_point_ = new ::std::string; + } + return insertion_point_; +} + +// optional string content = 15; +inline bool CodeGeneratorResponse_File::has_content() const { + return _has_bit(2); +} +inline void CodeGeneratorResponse_File::clear_content() { + if (content_ != &_default_content_) { + content_->clear(); + } + _clear_bit(2); +} +inline const ::std::string& CodeGeneratorResponse_File::content() const { + return *content_; +} +inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) { + _set_bit(2); + if (content_ == &_default_content_) { + content_ = new ::std::string; + } + content_->assign(value); +} +inline void CodeGeneratorResponse_File::set_content(const char* value) { + _set_bit(2); + if (content_ == &_default_content_) { + content_ = new ::std::string; + } + content_->assign(value); +} +inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) { + _set_bit(2); + if (content_ == &_default_content_) { + content_ = new ::std::string; + } + content_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* CodeGeneratorResponse_File::mutable_content() { + _set_bit(2); + if (content_ == &_default_content_) { + content_ = new ::std::string; + } + return content_; +} + +// ------------------------------------------------------------------- + +// CodeGeneratorResponse + +// optional string error = 1; +inline bool CodeGeneratorResponse::has_error() const { + return _has_bit(0); +} +inline void CodeGeneratorResponse::clear_error() { + if (error_ != &_default_error_) { + error_->clear(); + } + _clear_bit(0); +} +inline const ::std::string& CodeGeneratorResponse::error() const { + return *error_; +} +inline void CodeGeneratorResponse::set_error(const ::std::string& value) { + _set_bit(0); + if (error_ == &_default_error_) { + error_ = new ::std::string; + } + error_->assign(value); +} +inline void CodeGeneratorResponse::set_error(const char* value) { + _set_bit(0); + if (error_ == &_default_error_) { + error_ = new ::std::string; + } + error_->assign(value); +} +inline void CodeGeneratorResponse::set_error(const char* value, size_t size) { + _set_bit(0); + if (error_ == &_default_error_) { + error_ = new ::std::string; + } + error_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* CodeGeneratorResponse::mutable_error() { + _set_bit(0); + if (error_ == &_default_error_) { + error_ = new ::std::string; + } + return error_; +} + +// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; +inline int CodeGeneratorResponse::file_size() const { + return file_.size(); +} +inline void CodeGeneratorResponse::clear_file() { + file_.Clear(); +} +inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const { + return file_.Get(index); +} +inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) { + return file_.Mutable(index); +} +inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { + return file_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& +CodeGeneratorResponse::file() const { + return file_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* +CodeGeneratorResponse::mutable_file() { + return &file_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace compiler +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto new file mode 100644 index 0000000..4e928b0 --- /dev/null +++ b/src/google/protobuf/compiler/plugin.proto @@ -0,0 +1,145 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +package google.protobuf.compiler; + +import "google/protobuf/descriptor.proto"; + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + repeated FileDescriptorProto proto_file = 15; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocatino of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + } + repeated File file = 15; +} diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index d301f01..fae83a3 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -42,8 +42,9 @@ // performance-minded Python code leverage the fast C++ implementation // directly. -#include <utility> +#include <limits> #include <map> +#include <utility> #include <string> #include <vector> @@ -105,6 +106,13 @@ string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, const char kDescriptorKey[] = "DESCRIPTOR"; +// Should we generate generic services for this file? +inline bool HasGenericServices(const FileDescriptor *file) { + return file->service_count() > 0 && + file->options().py_generic_services(); +} + + // Prints the common boilerplate needed at the top of every .py // file output by this generator. void PrintTopBoilerplate( @@ -115,14 +123,21 @@ void PrintTopBoilerplate( "\n" "from google.protobuf import descriptor\n" "from google.protobuf import message\n" - "from google.protobuf import reflection\n" - "from google.protobuf import service\n" - "from google.protobuf import service_reflection\n"); + "from google.protobuf import reflection\n"); + if (HasGenericServices(file)) { + printer->Print( + "from google.protobuf import service\n" + "from google.protobuf import service_reflection\n"); + } + // Avoid circular imports if this module is descriptor_pb2. if (!descriptor_proto) { printer->Print( "from google.protobuf import descriptor_pb2\n"); } + printer->Print( + "# @@protoc_insertion_point(imports)\n"); + printer->Print("\n\n"); } @@ -150,10 +165,38 @@ string StringifyDefaultValue(const FieldDescriptor& field) { return SimpleItoa(field.default_value_int64()); case FieldDescriptor::CPPTYPE_UINT64: return SimpleItoa(field.default_value_uint64()); - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field.default_value_double()); - case FieldDescriptor::CPPTYPE_FLOAT: - return SimpleFtoa(field.default_value_float()); + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value = field.default_value_double(); + if (value == numeric_limits<double>::infinity()) { + // Python pre-2.6 on Windows does not parse "inf" correctly. However, + // a numeric literal that is too big for a double will become infinity. + return "1e10000"; + } else if (value == -numeric_limits<double>::infinity()) { + // See above. + return "-1e10000"; + } else if (value != value) { + // infinity * 0 = nan + return "(1e10000 * 0)"; + } else { + return SimpleDtoa(value); + } + } + case FieldDescriptor::CPPTYPE_FLOAT: { + float value = field.default_value_float(); + if (value == numeric_limits<float>::infinity()) { + // Python pre-2.6 on Windows does not parse "inf" correctly. However, + // a numeric literal that is too big for a double will become infinity. + return "1e10000"; + } else if (value == -numeric_limits<float>::infinity()) { + // See above. + return "-1e10000"; + } else if (value != value) { + // infinity - infinity = nan + return "(1e10000 * 0)"; + } else { + return SimpleFtoa(value); + } + } case FieldDescriptor::CPPTYPE_BOOL: return field.default_value_bool() ? "True" : "False"; case FieldDescriptor::CPPTYPE_ENUM: @@ -204,6 +247,10 @@ bool Generator::Generate(const FileDescriptor* file, StripString(&filename, ".", '/'); filename += ".py"; + FileDescriptorProto fdp; + file_->CopyTo(&fdp); + fdp.SerializeToString(&file_descriptor_serialized_); + scoped_ptr<io::ZeroCopyOutputStream> output(output_directory->Open(filename)); GOOGLE_CHECK(output.get()); @@ -211,6 +258,7 @@ bool Generator::Generate(const FileDescriptor* file, printer_ = &printer; PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto()); + PrintFileDescriptor(); PrintTopLevelEnums(); PrintTopLevelExtensions(); PrintAllNestedEnumsInFile(); @@ -224,7 +272,13 @@ bool Generator::Generate(const FileDescriptor* file, // since they need to call static RegisterExtension() methods on these // classes. FixForeignFieldsInExtensions(); - PrintServices(); + if (HasGenericServices(file)) { + PrintServices(); + } + + printer.Print( + "# @@protoc_insertion_point(module_scope)\n"); + return !printer.failed(); } @@ -238,6 +292,30 @@ void Generator::PrintImports() const { printer_->Print("\n"); } +// Prints the single file descriptor for this file. +void Generator::PrintFileDescriptor() const { + map<string, string> m; + m["descriptor_name"] = kDescriptorKey; + m["name"] = file_->name(); + m["package"] = file_->package(); + const char file_descriptor_template[] = + "$descriptor_name$ = descriptor.FileDescriptor(\n" + " name='$name$',\n" + " package='$package$',\n"; + printer_->Print(m, file_descriptor_template); + printer_->Indent(); + printer_->Print( + "serialized_pb='$value$'", + "value", strings::CHexEscape(file_descriptor_serialized_)); + + // TODO(falk): Also print options and fix the message_type, enum_type, + // service and extension later in the generation. + + printer_->Outdent(); + printer_->Print(")\n"); + printer_->Print("\n"); +} + // Prints descriptors and module-level constants for all top-level // enums defined in |file|. void Generator::PrintTopLevelEnums() const { @@ -277,12 +355,13 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor); m["name"] = enum_descriptor.name(); m["full_name"] = enum_descriptor.full_name(); - m["filename"] = enum_descriptor.name(); + m["file"] = kDescriptorKey; const char enum_descriptor_template[] = "$descriptor_name$ = descriptor.EnumDescriptor(\n" " name='$name$',\n" " full_name='$full_name$',\n" - " filename='$filename$',\n" + " filename=None,\n" + " file=$file$,\n" " values=[\n"; string options_string; enum_descriptor.options().SerializeToString(&options_string); @@ -295,9 +374,12 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { } printer_->Outdent(); printer_->Print("],\n"); + printer_->Print("containing_type=None,\n"); printer_->Print("options=$options_value$,\n", "options_value", OptionsValue("EnumOptions", CEscape(options_string))); + EnumDescriptorProto edp; + PrintSerializedPbInterval(enum_descriptor, edp); printer_->Outdent(); printer_->Print(")\n"); printer_->Print("\n"); @@ -362,15 +444,21 @@ void Generator::PrintServiceDescriptor( map<string, string> m; m["name"] = descriptor.name(); m["full_name"] = descriptor.full_name(); + m["file"] = kDescriptorKey; m["index"] = SimpleItoa(descriptor.index()); m["options_value"] = OptionsValue("ServiceOptions", options_string); const char required_function_arguments[] = "name='$name$',\n" "full_name='$full_name$',\n" + "file=$file$,\n" "index=$index$,\n" - "options=$options_value$,\n" - "methods=[\n"; + "options=$options_value$,\n"; printer_->Print(m, required_function_arguments); + + ServiceDescriptorProto sdp; + PrintSerializedPbInterval(descriptor, sdp); + + printer_->Print("methods=[\n"); for (int i = 0; i < descriptor.method_count(); ++i) { const MethodDescriptor* method = descriptor.method(i); string options_string; @@ -444,17 +532,27 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { map<string, string> m; m["name"] = message_descriptor.name(); m["full_name"] = message_descriptor.full_name(); - m["filename"] = message_descriptor.file()->name(); + m["file"] = kDescriptorKey; const char required_function_arguments[] = "name='$name$',\n" "full_name='$full_name$',\n" - "filename='$filename$',\n" - "containing_type=None,\n"; // TODO(robinson): Implement containing_type. + "filename=None,\n" + "file=$file$,\n" + "containing_type=None,\n"; printer_->Print(m, required_function_arguments); PrintFieldsInDescriptor(message_descriptor); PrintExtensionsInDescriptor(message_descriptor); - // TODO(robinson): implement printing of nested_types. - printer_->Print("nested_types=[], # TODO(robinson): Implement.\n"); + + // Nested types + printer_->Print("nested_types=["); + for (int i = 0; i < message_descriptor.nested_type_count(); ++i) { + const string nested_name = ModuleLevelDescriptorName( + *message_descriptor.nested_type(i)); + printer_->Print("$name$, ", "name", nested_name); + } + printer_->Print("],\n"); + + // Enum types printer_->Print("enum_types=[\n"); printer_->Indent(); for (int i = 0; i < message_descriptor.enum_type_count(); ++i) { @@ -468,8 +566,28 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { string options_string; message_descriptor.options().SerializeToString(&options_string); printer_->Print( - "options=$options_value$", - "options_value", OptionsValue("MessageOptions", options_string)); + "options=$options_value$,\n" + "is_extendable=$extendable$", + "options_value", OptionsValue("MessageOptions", options_string), + "extendable", message_descriptor.extension_range_count() > 0 ? + "True" : "False"); + printer_->Print(",\n"); + + // Extension ranges + printer_->Print("extension_ranges=["); + for (int i = 0; i < message_descriptor.extension_range_count(); ++i) { + const Descriptor::ExtensionRange* range = + message_descriptor.extension_range(i); + printer_->Print("($start$, $end$), ", + "start", SimpleItoa(range->start), + "end", SimpleItoa(range->end)); + } + printer_->Print("],\n"); + + // Serialization of proto + DescriptorProto edp; + PrintSerializedPbInterval(message_descriptor, edp); + printer_->Outdent(); printer_->Print(")\n"); } @@ -511,6 +629,12 @@ void Generator::PrintMessage( m["descriptor_key"] = kDescriptorKey; m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n"); + + printer_->Print( + "\n" + "# @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", message_descriptor.full_name()); + printer_->Outdent(); } @@ -527,16 +651,27 @@ void Generator::PrintNestedMessages( // Recursively fixes foreign fields in all nested types in |descriptor|, then // sets the message_type and enum_type of all message and enum fields to point // to their respective descriptors. +// Args: +// descriptor: descriptor to print fields for. +// containing_descriptor: if descriptor is a nested type, this is its +// containing type, or NULL if this is a root/top-level type. void Generator::FixForeignFieldsInDescriptor( - const Descriptor& descriptor) const { + const Descriptor& descriptor, + const Descriptor* containing_descriptor) const { for (int i = 0; i < descriptor.nested_type_count(); ++i) { - FixForeignFieldsInDescriptor(*descriptor.nested_type(i)); + FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor); } for (int i = 0; i < descriptor.field_count(); ++i) { const FieldDescriptor& field_descriptor = *descriptor.field(i); FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name"); } + + FixContainingTypeInDescriptor(descriptor, containing_descriptor); + for (int i = 0; i < descriptor.enum_type_count(); ++i) { + const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i); + FixContainingTypeInDescriptor(enum_descriptor, &descriptor); + } } // Sets any necessary message_type and enum_type attributes @@ -593,13 +728,29 @@ string Generator::FieldReferencingExpression( python_dict_name, field.name()); } +// Prints containing_type for nested descriptors or enum descriptors. +template <typename DescriptorT> +void Generator::FixContainingTypeInDescriptor( + const DescriptorT& descriptor, + const Descriptor* containing_descriptor) const { + if (containing_descriptor != NULL) { + const string nested_name = ModuleLevelDescriptorName(descriptor); + const string parent_name = ModuleLevelDescriptorName( + *containing_descriptor); + printer_->Print( + "$nested_name$.containing_type = $parent_name$;\n", + "nested_name", nested_name, + "parent_name", parent_name); + } +} + // Prints statements setting the message_type and enum_type fields in the // Python descriptor objects we've already output in ths file. We must // do this in a separate step due to circular references (otherwise, we'd // just set everything in the initial assignment statements). void Generator::FixForeignFieldsInDescriptors() const { for (int i = 0; i < file_->message_type_count(); ++i) { - FixForeignFieldsInDescriptor(*file_->message_type(i)); + FixForeignFieldsInDescriptor(*file_->message_type(i), NULL); } printer_->Print("\n"); } @@ -696,6 +847,7 @@ void Generator::PrintFieldDescriptor( m["type"] = SimpleItoa(field.type()); m["cpp_type"] = SimpleItoa(field.cpp_type()); m["label"] = SimpleItoa(field.label()); + m["has_default_value"] = field.has_default_value() ? "True" : "False"; m["default_value"] = StringifyDefaultValue(field); m["is_extension"] = is_extension ? "True" : "False"; m["options"] = OptionsValue("FieldOptions", options_string); @@ -703,13 +855,13 @@ void Generator::PrintFieldDescriptor( // these fields in correctly after all referenced descriptors have been // defined and/or imported (see FixForeignFieldsInDescriptors()). const char field_descriptor_decl[] = - "descriptor.FieldDescriptor(\n" - " name='$name$', full_name='$full_name$', index=$index$,\n" - " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n" - " default_value=$default_value$,\n" - " message_type=None, enum_type=None, containing_type=None,\n" - " is_extension=$is_extension$, extension_scope=None,\n" - " options=$options$)"; + "descriptor.FieldDescriptor(\n" + " name='$name$', full_name='$full_name$', index=$index$,\n" + " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n" + " has_default_value=$has_default_value$, default_value=$default_value$,\n" + " message_type=None, enum_type=None, containing_type=None,\n" + " is_extension=$is_extension$, extension_scope=None,\n" + " options=$options$)"; printer_->Print(m, field_descriptor_decl); } @@ -811,6 +963,29 @@ string Generator::ModuleLevelServiceDescriptorName( return name; } +// Prints standard constructor arguments serialized_start and serialized_end. +// Args: +// descriptor: The cpp descriptor to have a serialized reference. +// proto: A proto +// Example printer output: +// serialized_start=41, +// serialized_end=43, +// +template <typename DescriptorT, typename DescriptorProtoT> +void Generator::PrintSerializedPbInterval( + const DescriptorT& descriptor, DescriptorProtoT& proto) const { + descriptor.CopyTo(&proto); + string sp; + proto.SerializeToString(&sp); + int offset = file_descriptor_serialized_.find(sp); + GOOGLE_CHECK_GE(offset, 0); + + printer_->Print("serialized_start=$serialized_start$,\n" + "serialized_end=$serialized_end$,\n", + "serialized_start", SimpleItoa(offset), + "serialized_end", SimpleItoa(offset + sp.size())); +} + } // namespace python } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index 8b99d62..43c2087 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -71,6 +71,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { private: void PrintImports() const; + void PrintFileDescriptor() const; void PrintTopLevelEnums() const; void PrintAllNestedEnumsInFile() const; void PrintNestedEnums(const Descriptor& descriptor) const; @@ -97,13 +98,19 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { void PrintNestedMessages(const Descriptor& containing_descriptor) const; void FixForeignFieldsInDescriptors() const; - void FixForeignFieldsInDescriptor(const Descriptor& descriptor) const; + void FixForeignFieldsInDescriptor( + const Descriptor& descriptor, + const Descriptor* containing_descriptor) const; void FixForeignFieldsInField(const Descriptor* containing_type, const FieldDescriptor& field, const string& python_dict_name) const; string FieldReferencingExpression(const Descriptor* containing_type, const FieldDescriptor& field, const string& python_dict_name) const; + template <typename DescriptorT> + void FixContainingTypeInDescriptor( + const DescriptorT& descriptor, + const Descriptor* containing_descriptor) const; void FixForeignFieldsInExtensions() const; void FixForeignFieldsInExtension( @@ -126,10 +133,15 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { string ModuleLevelServiceDescriptorName( const ServiceDescriptor& descriptor) const; + template <typename DescriptorT, typename DescriptorProtoT> + void PrintSerializedPbInterval( + const DescriptorT& descriptor, DescriptorProtoT& proto) const; + // Very coarse-grained lock to ensure that Generate() is reentrant. - // Guards file_ and printer_. + // Guards file_, printer_ and file_descriptor_serialized_. mutable Mutex mutex_; mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable string file_descriptor_serialized_; mutable io::Printer* printer_; // Set in Generate(). Under mutex_. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc new file mode 100644 index 0000000..fde8876 --- /dev/null +++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc @@ -0,0 +1,116 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// TODO(kenton): Share code with the versions of this test in other languages? +// It seemed like parameterizing it would add more complexity than it is +// worth. + +#include <google/protobuf/compiler/python/python_generator.h> +#include <google/protobuf/compiler/command_line_interface.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/printer.h> + +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> +#include <google/protobuf/testing/file.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { +namespace { + +class TestGenerator : public CodeGenerator { + public: + TestGenerator() {} + ~TestGenerator() {} + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const { + TryInsert("test_pb2.py", "imports", output_directory); + TryInsert("test_pb2.py", "module_scope", output_directory); + TryInsert("test_pb2.py", "class_scope:foo.Bar", output_directory); + TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", output_directory); + return true; + } + + void TryInsert(const string& filename, const string& insertion_point, + OutputDirectory* output_directory) const { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->OpenForInsert(filename, insertion_point)); + io::Printer printer(output.get(), '$'); + printer.Print("// inserted $name$\n", "name", insertion_point); + } +}; + +// This test verifies that all the expected insertion points exist. It does +// not verify that they are correctly-placed; that would require actually +// compiling the output which is a bit more than I care to do for this test. +TEST(PythonPluginTest, PluginTest) { + File::WriteStringToFileOrDie( + "syntax = \"proto2\";\n" + "package foo;\n" + "message Bar {\n" + " message Baz {}\n" + "}\n", + TestTempDir() + "/test.proto"); + + google::protobuf::compiler::CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + python::Generator python_generator; + TestGenerator test_generator; + cli.RegisterGenerator("--python_out", &python_generator, ""); + cli.RegisterGenerator("--test_out", &test_generator, ""); + + string proto_path = "-I" + TestTempDir(); + string python_out = "--python_out=" + TestTempDir(); + string test_out = "--test_out=" + TestTempDir(); + + const char* argv[] = { + "protoc", + proto_path.c_str(), + python_out.c_str(), + test_out.c_str(), + "test.proto" + }; + + EXPECT_EQ(0, cli.Run(5, argv)); +} + +} // namespace +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc new file mode 100644 index 0000000..de46a3e --- /dev/null +++ b/src/google/protobuf/compiler/subprocess.cc @@ -0,0 +1,458 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) + +#include <google/protobuf/compiler/subprocess.h> + +#ifndef _WIN32 +#include <errno.h> +#include <sys/wait.h> +#include <signal.h> +#endif + +#include <algorithm> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/message.h> +#include <google/protobuf/stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { + +#ifdef _WIN32 + +static void CloseHandleOrDie(HANDLE handle) { + if (!CloseHandle(handle)) { + GOOGLE_LOG(FATAL) << "CloseHandle: " + << Subprocess::Win32ErrorMessage(GetLastError()); + } +} + +Subprocess::Subprocess() + : process_start_error_(ERROR_SUCCESS), + child_handle_(NULL), child_stdin_(NULL), child_stdout_(NULL) {} + +Subprocess::~Subprocess() { + if (child_stdin_ != NULL) { + CloseHandleOrDie(child_stdin_); + } + if (child_stdout_ != NULL) { + CloseHandleOrDie(child_stdout_); + } +} + +void Subprocess::Start(const string& program, SearchMode search_mode) { + // Create the pipes. + HANDLE stdin_pipe_read; + HANDLE stdin_pipe_write; + HANDLE stdout_pipe_read; + HANDLE stdout_pipe_write; + + if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) { + GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); + } + if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) { + GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); + } + + // Make child side of the pipes inheritable. + if (!SetHandleInformation(stdin_pipe_read, + HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { + GOOGLE_LOG(FATAL) << "SetHandleInformation: " + << Win32ErrorMessage(GetLastError()); + } + if (!SetHandleInformation(stdout_pipe_write, + HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { + GOOGLE_LOG(FATAL) << "SetHandleInformation: " + << Win32ErrorMessage(GetLastError()); + } + + // Setup STARTUPINFO to redirect handles. + STARTUPINFO startup_info; + ZeroMemory(&startup_info, sizeof(startup_info)); + startup_info.cb = sizeof(startup_info); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = stdin_pipe_read; + startup_info.hStdOutput = stdout_pipe_write; + startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); + + if (startup_info.hStdError == INVALID_HANDLE_VALUE) { + GOOGLE_LOG(FATAL) << "GetStdHandle: " + << Win32ErrorMessage(GetLastError()); + } + + // CreateProcess() mutates its second parameter. WTF? + char* name_copy = strdup(program.c_str()); + + // Create the process. + PROCESS_INFORMATION process_info; + + if (CreateProcess((search_mode == SEARCH_PATH) ? NULL : program.c_str(), + (search_mode == SEARCH_PATH) ? name_copy : NULL, + NULL, // process security attributes + NULL, // thread security attributes + TRUE, // inherit handles? + 0, // obscure creation flags + NULL, // environment (inherit from parent) + NULL, // current directory (inherit from parent) + &startup_info, + &process_info)) { + child_handle_ = process_info.hProcess; + CloseHandleOrDie(process_info.hThread); + child_stdin_ = stdin_pipe_write; + child_stdout_ = stdout_pipe_read; + } else { + process_start_error_ = GetLastError(); + CloseHandleOrDie(stdin_pipe_write); + CloseHandleOrDie(stdout_pipe_read); + } + + CloseHandleOrDie(stdin_pipe_read); + CloseHandleOrDie(stdout_pipe_write); + free(name_copy); +} + +bool Subprocess::Communicate(const Message& input, Message* output, + string* error) { + if (process_start_error_ != ERROR_SUCCESS) { + *error = Win32ErrorMessage(process_start_error_); + return false; + } + + GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first."; + + string input_data = input.SerializeAsString(); + string output_data; + + int input_pos = 0; + + while (child_stdout_ != NULL) { + HANDLE handles[2]; + int handle_count = 0; + + if (child_stdin_ != NULL) { + handles[handle_count++] = child_stdin_; + } + if (child_stdout_ != NULL) { + handles[handle_count++] = child_stdout_; + } + + DWORD wait_result = + WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE); + + HANDLE signaled_handle; + if (wait_result >= WAIT_OBJECT_0 && + wait_result < WAIT_OBJECT_0 + handle_count) { + signaled_handle = handles[wait_result - WAIT_OBJECT_0]; + } else if (wait_result == WAIT_FAILED) { + GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: " + << Win32ErrorMessage(GetLastError()); + } else { + GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: Unexpected return code: " + << wait_result; + } + + if (signaled_handle == child_stdin_) { + DWORD n; + if (!WriteFile(child_stdin_, + input_data.data() + input_pos, + input_data.size() - input_pos, + &n, NULL)) { + // Child closed pipe. Presumably it will report an error later. + // Pretend we're done for now. + input_pos = input_data.size(); + } else { + input_pos += n; + } + + if (input_pos == input_data.size()) { + // We're done writing. Close. + CloseHandleOrDie(child_stdin_); + child_stdin_ = NULL; + } + } else if (signaled_handle == child_stdout_) { + char buffer[4096]; + DWORD n; + + if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) { + // We're done reading. Close. + CloseHandleOrDie(child_stdout_); + child_stdout_ = NULL; + } else { + output_data.append(buffer, n); + } + } + } + + if (child_stdin_ != NULL) { + // Child did not finish reading input before it closed the output. + // Presumably it exited with an error. + CloseHandleOrDie(child_stdin_); + child_stdin_ = NULL; + } + + DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE); + + if (wait_result == WAIT_FAILED) { + GOOGLE_LOG(FATAL) << "WaitForSingleObject: " + << Win32ErrorMessage(GetLastError()); + } else if (wait_result != WAIT_OBJECT_0) { + GOOGLE_LOG(FATAL) << "WaitForSingleObject: Unexpected return code: " + << wait_result; + } + + DWORD exit_code; + if (!GetExitCodeProcess(child_handle_, &exit_code)) { + GOOGLE_LOG(FATAL) << "GetExitCodeProcess: " + << Win32ErrorMessage(GetLastError()); + } + + CloseHandleOrDie(child_handle_); + child_handle_ = NULL; + + if (exit_code != 0) { + *error = strings::Substitute( + "Plugin failed with status code $0.", exit_code); + return false; + } + + if (!output->ParseFromString(output_data)) { + *error = "Plugin output is unparseable: " + CEscape(output_data); + return false; + } + + return true; +} + +string Subprocess::Win32ErrorMessage(DWORD error_code) { + char* message; + + // WTF? + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, 0, + (LPTSTR)&message, // NOT A BUG! + 0, NULL); + + string result = message; + LocalFree(message); + return result; +} + +// =================================================================== + +#else // _WIN32 + +Subprocess::Subprocess() + : child_pid_(-1), child_stdin_(-1), child_stdout_(-1) {} + +Subprocess::~Subprocess() { + if (child_stdin_ != -1) { + close(child_stdin_); + } + if (child_stdout_ != -1) { + close(child_stdout_); + } +} + +void Subprocess::Start(const string& program, SearchMode search_mode) { + // Note that we assume that there are no other threads, thus we don't have to + // do crazy stuff like using socket pairs or avoiding libc locks. + + // [0] is read end, [1] is write end. + int stdin_pipe[2]; + int stdout_pipe[2]; + + pipe(stdin_pipe); + pipe(stdout_pipe); + + char* argv[2] = { strdup(program.c_str()), NULL }; + + child_pid_ = fork(); + if (child_pid_ == -1) { + GOOGLE_LOG(FATAL) << "fork: " << strerror(errno); + } else if (child_pid_ == 0) { + // We are the child. + dup2(stdin_pipe[0], STDIN_FILENO); + dup2(stdout_pipe[1], STDOUT_FILENO); + + close(stdin_pipe[0]); + close(stdin_pipe[1]); + close(stdout_pipe[0]); + close(stdout_pipe[1]); + + switch (search_mode) { + case SEARCH_PATH: + execvp(argv[0], argv); + break; + case EXACT_NAME: + execv(argv[0], argv); + break; + } + + // Write directly to STDERR_FILENO to avoid stdio code paths that may do + // stuff that is unsafe here. + write(STDERR_FILENO, argv[0], strlen(argv[0])); + const char* message = ": program not found or is not executable\n"; + write(STDERR_FILENO, message, strlen(message)); + + // Must use _exit() rather than exit() to avoid flushing output buffers + // that will also be flushed by the parent. + _exit(1); + } else { + free(argv[0]); + + close(stdin_pipe[0]); + close(stdout_pipe[1]); + + child_stdin_ = stdin_pipe[1]; + child_stdout_ = stdout_pipe[0]; + } +} + +bool Subprocess::Communicate(const Message& input, Message* output, + string* error) { + + GOOGLE_CHECK_NE(child_stdin_, -1) << "Must call Start() first."; + + // The "sighandler_t" typedef is GNU-specific, so define our own. + typedef void SignalHandler(int); + + // Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us. + SignalHandler* old_pipe_handler = signal(SIGPIPE, SIG_IGN); + + string input_data = input.SerializeAsString(); + string output_data; + + int input_pos = 0; + int max_fd = max(child_stdin_, child_stdout_); + + while (child_stdout_ != -1) { + fd_set read_fds; + fd_set write_fds; + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + if (child_stdout_ != -1) { + FD_SET(child_stdout_, &read_fds); + } + if (child_stdin_ != -1) { + FD_SET(child_stdin_, &write_fds); + } + + if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) { + if (errno == EINTR) { + // Interrupted by signal. Try again. + continue; + } else { + GOOGLE_LOG(FATAL) << "select: " << strerror(errno); + } + } + + if (child_stdin_ != -1 && FD_ISSET(child_stdin_, &write_fds)) { + int n = write(child_stdin_, input_data.data() + input_pos, + input_data.size() - input_pos); + if (n < 0) { + // Child closed pipe. Presumably it will report an error later. + // Pretend we're done for now. + input_pos = input_data.size(); + } else { + input_pos += n; + } + + if (input_pos == input_data.size()) { + // We're done writing. Close. + close(child_stdin_); + child_stdin_ = -1; + } + } + + if (child_stdout_ != -1 && FD_ISSET(child_stdout_, &read_fds)) { + char buffer[4096]; + int n = read(child_stdout_, buffer, sizeof(buffer)); + + if (n > 0) { + output_data.append(buffer, n); + } else { + // We're done reading. Close. + close(child_stdout_); + child_stdout_ = -1; + } + } + } + + if (child_stdin_ != -1) { + // Child did not finish reading input before it closed the output. + // Presumably it exited with an error. + close(child_stdin_); + child_stdin_ = -1; + } + + int status; + while (waitpid(child_pid_, &status, 0) == -1) { + if (errno != EINTR) { + GOOGLE_LOG(FATAL) << "waitpid: " << strerror(errno); + } + } + + // Restore SIGPIPE handling. + signal(SIGPIPE, old_pipe_handler); + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) { + int error_code = WEXITSTATUS(status); + *error = strings::Substitute( + "Plugin failed with status code $0.", error_code); + return false; + } + } else if (WIFSIGNALED(status)) { + int signal = WTERMSIG(status); + *error = strings::Substitute( + "Plugin killed by signal $0.", signal); + return false; + } else { + *error = "Neither WEXITSTATUS nor WTERMSIG is true?"; + return false; + } + + if (!output->ParseFromString(output_data)) { + *error = "Plugin output is unparseable."; + return false; + } + + return true; +} + +#endif // !_WIN32 + +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_field.h b/src/google/protobuf/compiler/subprocess.h index 1530778..f9e8ae8 100644 --- a/src/google/protobuf/compiler/javamicro/javamicro_field.h +++ b/src/google/protobuf/compiler/subprocess.h @@ -29,70 +29,79 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ +#ifndef GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__ +#define GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN // right... +#include <windows.h> +#else // _WIN32 +#include <sys/types.h> +#include <unistd.h> +#endif // !_WIN32 #include <string> #include <google/protobuf/stubs/common.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/compiler/javamicro/javamicro_params.h> namespace google { namespace protobuf { - namespace io { - class Printer; // printer.h - } -} -namespace protobuf { +class Message; + namespace compiler { -namespace javamicro { -class FieldGenerator { +// Utility class for launching sub-processes. +class Subprocess { public: - //FieldGenerator() {} - FieldGenerator(const Params& params) : params_(params) {} - virtual ~FieldGenerator(); - - virtual void GenerateMembers(io::Printer* printer) const = 0; - virtual void GenerateMergingCode(io::Printer* printer) const = 0; - virtual void GenerateParsingCode(io::Printer* printer) const = 0; - virtual void GenerateSerializationCode(io::Printer* printer) const = 0; - virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; - - virtual string GetBoxedType() const = 0; + Subprocess(); + ~Subprocess(); + + enum SearchMode { + SEARCH_PATH, // Use PATH environment variable. + EXACT_NAME // Program is an exact file name; don't use the PATH. + }; + + // Start the subprocess. Currently we don't provide a way to specify + // arguments as protoc plugins don't have any. + void Start(const string& program, SearchMode search_mode); + + // Serialize the input message and pipe it to the subprocess's stdin, then + // close the pipe. Meanwhile, read from the subprocess's stdout and parse + // the data into *output. All this is done carefully to avoid deadlocks. + // Returns true if successful. On any sort of error, returns false and sets + // *error to a description of the problem. + bool Communicate(const Message& input, Message* output, string* error); + +#ifdef _WIN32 + // Given an error code, returns a human-readable error message. This is + // defined here so that CommandLineInterface can share it. + static string Subprocess::Win32ErrorMessage(DWORD error_code); +#endif - protected: - const Params& params_; private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); -}; - -// Convenience class which constructs FieldGenerators for a Descriptor. -class FieldGeneratorMap { - public: - explicit FieldGeneratorMap(const Descriptor* descriptor, const Params ¶ms); - ~FieldGeneratorMap(); +#ifdef _WIN32 + DWORD process_start_error_; + HANDLE child_handle_; - const FieldGenerator& get(const FieldDescriptor* field) const; - const FieldGenerator& get_extension(int index) const; + // The file handles for our end of the child's pipes. We close each and + // set it to NULL when no longer needed. + HANDLE child_stdin_; + HANDLE child_stdout_; - private: - const Descriptor* descriptor_; - scoped_array<scoped_ptr<FieldGenerator> > field_generators_; - scoped_array<scoped_ptr<FieldGenerator> > extension_generators_; +#else // _WIN32 + pid_t child_pid_; - static FieldGenerator* MakeGenerator(const FieldDescriptor* field, const Params ¶ms); + // The file descriptors for our end of the child's pipes. We close each and + // set it to -1 when no longer needed. + int child_stdin_; + int child_stdout_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); +#endif // !_WIN32 }; -} // namespace javamicro } // namespace compiler } // namespace protobuf } // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ +#endif // GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__ diff --git a/src/google/protobuf/unittest_recursive_micro.proto b/src/google/protobuf/compiler/test_plugin.cc index a256852..5cbbf3d 100644 --- a/src/google/protobuf/unittest_recursive_micro.proto +++ b/src/google/protobuf/compiler/test_plugin.cc @@ -28,20 +28,24 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Author: wink@google.com (Wink Saville) +// Author: kenton@google.com (Kenton Varda) // +// This is a dummy code generator plugin used by +// command_line_interface_unittest. -package protobuf_unittest_import; +#include <string> +#include <stdlib.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/compiler/mock_code_generator.h> +#include <google/protobuf/stubs/strutil.h> -option java_package = "com.google.protobuf.micro"; +int main(int argc, char* argv[]) { +#ifdef _MSC_VER + // Don't print a silly message or stick a modal dialog box in my face, + // please. + _set_abort_behavior(0, ~0); +#endif // !_MSC_VER -message RecursiveMessageMicro { - message NestedMessage { - optional RecursiveMessageMicro a = 1; - } - - required int32 id = 1; - optional NestedMessage nested_message = 2; - optional RecursiveMessageMicro optional_recursive_message_micro = 3; - repeated RecursiveMessageMicro repeated_recursive_message_micro = 4; + google::protobuf::compiler::MockCodeGenerator generator("test_plugin"); + return google::protobuf::compiler::PluginMain(argc, argv, &generator); } diff --git a/src/google/protobuf/compiler/zip_output_unittest.sh b/src/google/protobuf/compiler/zip_output_unittest.sh new file mode 100755 index 0000000..259d5d2 --- /dev/null +++ b/src/google/protobuf/compiler/zip_output_unittest.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# +# Protocol Buffers - Google's data interchange format +# Copyright 2009 Google Inc. All rights reserved. +# http://code.google.com/p/protobuf/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Author: kenton@google.com (Kenton Varda) +# +# Test protoc's zip output mode. + +fail() { + echo "$@" >&2 + exit 1 +} + +echo ' + option java_multiple_files = true; + option java_package = "test.jar"; + option java_outer_classname = "Outer"; + message Foo {} + message Bar {} +' > testzip.proto + +./protoc --cpp_out=testzip.zip --python_out=testzip.zip --java_out=testzip.jar \ + testzip.proto || fail 'protoc failed.' + +echo "Testing output to zip..." +if unzip -h > /dev/null; then + unzip -t testzip.zip > testzip.list || fail 'unzip failed.' + + grep 'testing: testzip\.pb\.cc *OK$' testzip.list > /dev/null \ + || fail 'testzip.pb.cc not found in output zip.' + grep 'testing: testzip\.pb\.h *OK$' testzip.list > /dev/null \ + || fail 'testzip.pb.h not found in output zip.' + grep 'testing: testzip_pb2\.py *OK$' testzip.list > /dev/null \ + || fail 'testzip_pb2.py not found in output zip.' + grep -i 'manifest' testzip.list > /dev/null \ + && fail 'Zip file contained manifest.' +else + echo "Warning: 'unzip' command not available. Skipping test." +fi + +echo "Testing output to jar..." +if jar c testzip.proto > /dev/null; then + jar tf testzip.jar > testzip.list || fail 'jar failed.' + + grep '^test/jar/Foo\.java$' testzip.list > /dev/null \ + || fail 'Foo.java not found in output jar.' + grep '^test/jar/Bar\.java$' testzip.list > /dev/null \ + || fail 'Bar.java not found in output jar.' + grep '^test/jar/Outer\.java$' testzip.list > /dev/null \ + || fail 'Outer.java not found in output jar.' + grep '^META-INF/MANIFEST\.MF$' testzip.list > /dev/null \ + || fail 'Manifest not ofund in output jar.' +else + echo "Warning: 'jar' command not available. Skipping test." +fi + +echo PASS diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc new file mode 100644 index 0000000..53c1877 --- /dev/null +++ b/src/google/protobuf/compiler/zip_writer.cc @@ -0,0 +1,188 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: ambrose@google.com (Ambrose Feinstein), +// kenton@google.com (Kenton Varda) +// +// Based on http://www.pkware.com/documents/casestudies/APPNOTE.TXT + +#include <google/protobuf/compiler/zip_writer.h> +#include <google/protobuf/io/coded_stream.h> + +namespace google { +namespace protobuf { +namespace compiler { + +static const uint32 kCRC32Table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +static uint32 ComputeCRC32(const string &buf) { + uint32 x = ~0U; + for (int i = 0; i < buf.size(); ++i) { + unsigned char c = buf[i]; + x = kCRC32Table[(x ^ c) & 0xff] ^ (x >> 8); + } + return ~x; +} + +static void WriteShort(io::CodedOutputStream *out, uint16 val) { + uint8 p[2]; + p[0] = static_cast<uint8>(val); + p[1] = static_cast<uint8>(val >> 8); + out->WriteRaw(p, 2); +} + +ZipWriter::ZipWriter(io::ZeroCopyOutputStream* raw_output) + : raw_output_(raw_output) {} +ZipWriter::~ZipWriter() {} + +bool ZipWriter::Write(const string& filename, const string& contents) { + FileInfo info; + + info.name = filename; + uint16 filename_size = filename.size(); + info.offset = raw_output_->ByteCount(); + info.size = contents.size(); + info.crc32 = ComputeCRC32(contents); + + files_.push_back(info); + + // write file header + io::CodedOutputStream output(raw_output_); + output.WriteLittleEndian32(0x04034b50); // magic + WriteShort(&output, 10); // version needed to extract + WriteShort(&output, 0); // flags + WriteShort(&output, 0); // compression method: stored + WriteShort(&output, 0); // last modified time + WriteShort(&output, 0); // last modified date + output.WriteLittleEndian32(info.crc32); // crc-32 + output.WriteLittleEndian32(info.size); // compressed size + output.WriteLittleEndian32(info.size); // uncompressed size + WriteShort(&output, filename_size); // file name length + WriteShort(&output, 0); // extra field length + output.WriteString(filename); // file name + output.WriteString(contents); // file data + + return !output.HadError(); +} + +bool ZipWriter::WriteDirectory() { + uint16 num_entries = files_.size(); + uint32 dir_ofs = raw_output_->ByteCount(); + + // write central directory + io::CodedOutputStream output(raw_output_); + for (int i = 0; i < num_entries; ++i) { + const string &filename = files_[i].name; + uint16 filename_size = filename.size(); + uint32 crc32 = files_[i].crc32; + uint32 size = files_[i].size; + uint32 offset = files_[i].offset; + + output.WriteLittleEndian32(0x02014b50); // magic + WriteShort(&output, 10); // version made by + WriteShort(&output, 10); // version needed to extract + WriteShort(&output, 0); // flags + WriteShort(&output, 0); // compression method: stored + WriteShort(&output, 0); // last modified time + WriteShort(&output, 0); // last modified date + output.WriteLittleEndian32(crc32); // crc-32 + output.WriteLittleEndian32(size); // compressed size + output.WriteLittleEndian32(size); // uncompressed size + WriteShort(&output, filename_size); // file name length + WriteShort(&output, 0); // extra field length + WriteShort(&output, 0); // file comment length + WriteShort(&output, 0); // starting disk number + WriteShort(&output, 0); // internal file attributes + output.WriteLittleEndian32(0); // external file attributes + output.WriteLittleEndian32(offset); // local header offset + output.WriteString(filename); // file name + } + uint32 dir_len = output.ByteCount(); + + // write end of central directory marker + output.WriteLittleEndian32(0x06054b50); // magic + WriteShort(&output, 0); // disk number + WriteShort(&output, 0); // disk with start of central directory + WriteShort(&output, num_entries); // central directory entries (this disk) + WriteShort(&output, num_entries); // central directory entries (total) + output.WriteLittleEndian32(dir_len); // central directory byte size + output.WriteLittleEndian32(dir_ofs); // central directory offset + WriteShort(&output, 0); // comment length + + return output.HadError(); +} + +} // namespace google +} // namespace protobuf +} // namespace compiler diff --git a/src/google/protobuf/unittest_simple_micro.proto b/src/google/protobuf/compiler/zip_writer.h index 057bf3d..4289553 100644 --- a/src/google/protobuf/unittest_simple_micro.proto +++ b/src/google/protobuf/compiler/zip_writer.h @@ -28,25 +28,36 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Author: wink@google.com (Wink Saville) -// +// Author: kenton@google.com (Kenton Varda) + +#include <vector> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/zero_copy_stream.h> + +namespace google { +namespace protobuf { +namespace compiler { -package protobuf_unittest_import; +class ZipWriter { + public: + ZipWriter(io::ZeroCopyOutputStream* raw_output); + ~ZipWriter(); -option java_package = "com.google.protobuf.micro"; + bool Write(const string& filename, const string& contents); + bool WriteDirectory(); -message SimpleMessageMicro { - message NestedMessage { - optional int32 bb = 1; - } + private: + struct FileInfo { + string name; + uint32 offset; + uint32 size; + uint32 crc32; + }; - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - } + io::ZeroCopyOutputStream* raw_output_; + vector<FileInfo> files_; +}; - optional int32 d = 1 [default = 123]; - optional NestedMessage nested_msg = 2; - optional NestedEnum default_nested_enum = 3 [default = BAZ]; -} +} // namespace google +} // namespace protobuf +} // namespace compiler diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index a12e4e7..81c4ac0 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -37,6 +37,7 @@ #include <set> #include <vector> #include <algorithm> +#include <limits> #include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor_database.h> @@ -796,6 +797,7 @@ bool DescriptorPool::InternalIsFileLoaded(const string& filename) const { namespace { + EncodedDescriptorDatabase* generated_database_ = NULL; DescriptorPool* generated_pool_ = NULL; GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_); @@ -810,6 +812,7 @@ void DeleteGeneratedPool() { void InitGeneratedPool() { generated_database_ = new EncodedDescriptorDatabase; generated_pool_ = new DescriptorPool(generated_database_); + internal::OnShutdown(&DeleteGeneratedPool); } @@ -2998,12 +3001,28 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, strtou64(proto.default_value().c_str(), &end_pos, 0); break; case FieldDescriptor::CPPTYPE_FLOAT: - result->default_value_float_ = - NoLocaleStrtod(proto.default_value().c_str(), &end_pos); + if (proto.default_value() == "inf") { + result->default_value_float_ = numeric_limits<float>::infinity(); + } else if (proto.default_value() == "-inf") { + result->default_value_float_ = -numeric_limits<float>::infinity(); + } else if (proto.default_value() == "nan") { + result->default_value_float_ = numeric_limits<float>::quiet_NaN(); + } else { + result->default_value_float_ = + NoLocaleStrtod(proto.default_value().c_str(), &end_pos); + } break; case FieldDescriptor::CPPTYPE_DOUBLE: - result->default_value_double_ = - NoLocaleStrtod(proto.default_value().c_str(), &end_pos); + if (proto.default_value() == "inf") { + result->default_value_double_ = numeric_limits<double>::infinity(); + } else if (proto.default_value() == "-inf") { + result->default_value_double_ = -numeric_limits<double>::infinity(); + } else if (proto.default_value() == "nan") { + result->default_value_double_ = numeric_limits<double>::quiet_NaN(); + } else { + result->default_value_double_ = + NoLocaleStrtod(proto.default_value().c_str(), &end_pos); + } break; case FieldDescriptor::CPPTYPE_BOOL: if (proto.default_value() == "true") { @@ -3651,17 +3670,11 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, } // Only repeated primitive fields may be packed. - if (field->options().packed()) { - if (!field->is_repeated() || - field->type() == FieldDescriptor::TYPE_STRING || - field->type() == FieldDescriptor::TYPE_GROUP || - field->type() == FieldDescriptor::TYPE_MESSAGE || - field->type() == FieldDescriptor::TYPE_BYTES) { - AddError( - field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "[packed = true] can only be specified for repeated primitive fields."); - } + if (field->options().packed() && !field->is_packable()) { + AddError( + field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "[packed = true] can only be specified for repeated primitive fields."); } // Note: Default instance may not yet be initialized here, so we have to diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 5b629a5..7f87dd8 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -395,6 +395,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptor { bool is_required() const; // shorthand for label() == LABEL_REQUIRED bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL bool is_repeated() const; // shorthand for label() == LABEL_REPEATED + bool is_packable() const; // shorthand for is_repeated() && + // IsTypePackable(type()) // Index of this field within the message's field array, or the file or // extension scope's extensions array. @@ -474,6 +476,9 @@ class LIBPROTOBUF_EXPORT FieldDescriptor { // Helper method to get the CppType for a particular Type. static CppType TypeToCppType(Type type); + // Return true iff [packed = true] is valid for fields of this type. + static inline bool IsTypePackable(Type field_type); + private: typedef FieldOptions OptionsType; @@ -1069,10 +1074,6 @@ class LIBPROTOBUF_EXPORT DescriptorPool { // These methods may contain hidden pitfalls and may be removed in a // future library version. - // DEPRECATED: Use of underlays can lead to many subtle gotchas. Instead, - // try to formulate what you want to do in terms of DescriptorDatabases. - // This constructor will be removed soon. - // // Create a DescriptorPool which is overlaid on top of some other pool. // If you search for a descriptor in the overlay and it is not found, the // underlay will be searched as a backup. If the underlay has its own @@ -1090,6 +1091,9 @@ class LIBPROTOBUF_EXPORT DescriptorPool { // types directly into generated_pool(): this is not allowed, and would be // bad design anyway. So, instead, you could use generated_pool() as an // underlay for a new DescriptorPool in which you add only the new file. + // + // WARNING: Use of underlays can lead to many subtle gotchas. Instead, + // try to formulate what you want to do in terms of DescriptorDatabases. explicit DescriptorPool(const DescriptorPool* underlay); // Called by generated classes at init time to add their descriptors to @@ -1294,6 +1298,10 @@ inline bool FieldDescriptor::is_repeated() const { return label() == LABEL_REPEATED; } +inline bool FieldDescriptor::is_packable() const { + return is_repeated() && IsTypePackable(type()); +} + // To save space, index() is computed by looking at the descriptor's position // in the parent's array of children. inline int FieldDescriptor::index() const { @@ -1342,6 +1350,13 @@ inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { return kTypeToCppTypeMap[type]; } +inline bool FieldDescriptor::IsTypePackable(Type field_type) { + return (field_type != FieldDescriptor::TYPE_STRING && + field_type != FieldDescriptor::TYPE_GROUP && + field_type != FieldDescriptor::TYPE_MESSAGE && + field_type != FieldDescriptor::TYPE_BYTES); +} + inline const FileDescriptor* FileDescriptor::dependency(int index) const { return dependencies_[index]; } diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index a68a6a4..f61e7cd 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -8,6 +8,7 @@ #include <google/protobuf/descriptor.h> #include <google/protobuf/reflection_ops.h> #include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) namespace google { namespace protobuf { @@ -250,11 +251,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(MethodDescriptorProto)); FileOptions_descriptor_ = file->message_type(8); - static const int FileOptions_offsets_[5] = { + static const int FileOptions_offsets_[8] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_), }; FileOptions_reflection_ = @@ -552,43 +556,47 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { "ptions\"\177\n\025MethodDescriptorProto\022\014\n\004name\030" "\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013output_type" "\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.protobu" - "f.MethodOptions\"\271\002\n\013FileOptions\022\024\n\014java_" + "f.MethodOptions\"\244\003\n\013FileOptions\022\024\n\014java_" "package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 " "\001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022" "F\n\014optimize_for\030\t \001(\0162).google.protobuf." - "FileOptions.OptimizeMode:\005SPEED\022C\n\024unint" - "erpreted_option\030\347\007 \003(\0132$.google.protobuf" - ".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005" - "SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003" - "*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOptions\022&\n\027messag" - "e_set_wire_format\030\001 \001(\010:\005false\022.\n\037no_sta" - "ndard_descriptor_accessor\030\002 \001(\010:\005false\022C" - "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p" - "rotobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\200" - "\002\n\014FieldOptions\0222\n\005ctype\030\001 \001(\0162#.google." - "protobuf.FieldOptions.CType\022\016\n\006packed\030\002 " - "\001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experi" - "mental_map_key\030\t \001(\t\022C\n\024uninterpreted_op" - "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre" - "tedOption\"#\n\005CType\022\010\n\004CORD\020\001\022\020\n\014STRING_P" - "IECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022C\n\024unin" - "terpreted_option\030\347\007 \003(\0132$.google.protobu" - "f.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020Enum" - "ValueOptions\022C\n\024uninterpreted_option\030\347\007 " - "\003(\0132$.google.protobuf.UninterpretedOptio" - "n*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024uninte" - "rpreted_option\030\347\007 \003(\0132$.google.protobuf." - "UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethod" - "Options\022C\n\024uninterpreted_option\030\347\007 \003(\0132$" - ".google.protobuf.UninterpretedOption*\t\010\350" - "\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedOption\022;\n\004name\030" - "\002 \003(\0132-.google.protobuf.UninterpretedOpt" - "ion.NamePart\022\030\n\020identifier_value\030\003 \001(\t\022\032" - "\n\022positive_int_value\030\004 \001(\004\022\032\n\022negative_i" - "nt_value\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014" - "string_value\030\007 \001(\014\0323\n\010NamePart\022\021\n\tname_p" - "art\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010B)\n\023com.g" - "oogle.protobufB\020DescriptorProtosH\001", 3554); + "FileOptions.OptimizeMode:\005SPEED\022!\n\023cc_ge" + "neric_services\030\020 \001(\010:\004true\022#\n\025java_gener" + "ic_services\030\021 \001(\010:\004true\022!\n\023py_generic_se" + "rvices\030\022 \001(\010:\004true\022C\n\024uninterpreted_opti" + "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete" + "dOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCO" + "DE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270" + "\001\n\016MessageOptions\022&\n\027message_set_wire_fo" + "rmat\030\001 \001(\010:\005false\022.\n\037no_standard_descrip" + "tor_accessor\030\002 \001(\010:\005false\022C\n\024uninterpret" + "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint" + "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptio" + "ns\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.Fiel" + "dOptions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\031" + "\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experimenta" + "l_map_key\030\t \001(\t\022C\n\024uninterpreted_option\030" + "\347\007 \003(\0132$.google.protobuf.UninterpretedOp" + "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S" + "TRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022" + "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google." + "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"" + "b\n\020EnumValueOptions\022C\n\024uninterpreted_opt" + "ion\030\347\007 \003(\0132$.google.protobuf.Uninterpret" + "edOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n" + "\024uninterpreted_option\030\347\007 \003(\0132$.google.pr" + "otobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n" + "\rMethodOptions\022C\n\024uninterpreted_option\030\347" + "\007 \003(\0132$.google.protobuf.UninterpretedOpt" + "ion*\t\010\350\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedOption\022;" + "\n\004name\030\002 \003(\0132-.google.protobuf.Uninterpr" + "etedOption.NamePart\022\030\n\020identifier_value\030" + "\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022neg" + "ative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006 " + "\001(\001\022\024\n\014string_value\030\007 \001(\014\0323\n\010NamePart\022\021\n" + "\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010B)" + "\n\023com.google.protobufB\020DescriptorProtosH" + "\001", 3681); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); FileDescriptorSet::default_instance_ = new FileDescriptorSet(); @@ -644,14 +652,16 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto { const int FileDescriptorSet::kFileFieldNumber; #endif // !_MSC_VER -FileDescriptorSet::FileDescriptorSet() { +FileDescriptorSet::FileDescriptorSet() + : ::google::protobuf::Message() { SharedCtor(); } void FileDescriptorSet::InitAsDefaultInstance() { } -FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) { +FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -670,6 +680,11 @@ void FileDescriptorSet::SharedDtor() { } } +void FileDescriptorSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() { protobuf_AssignDescriptorsOnce(); return FileDescriptorSet_descriptor_; @@ -699,13 +714,14 @@ bool FileDescriptorSet::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.FileDescriptorProto file = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_file())); + } else { goto handle_uninterpreted; } - parse_file: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_file())); if (input->ExpectTag(10)) goto parse_file; if (input->ExpectAtEnd()) return true; break; @@ -729,15 +745,9 @@ bool FileDescriptorSet::MergePartialFromCodedStream( void FileDescriptorSet::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - FileDescriptorSet::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // repeated .google.protobuf.FileDescriptorProto file = 1; for (int i = 0; i < this->file_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 1, this->file(i), output); } @@ -779,7 +789,9 @@ int FileDescriptorSet::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -854,7 +866,8 @@ const int FileDescriptorProto::kExtensionFieldNumber; const int FileDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -FileDescriptorProto::FileDescriptorProto() { +FileDescriptorProto::FileDescriptorProto() + : ::google::protobuf::Message() { SharedCtor(); } @@ -862,7 +875,8 @@ void FileDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance()); } -FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) { +FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -891,6 +905,11 @@ void FileDescriptorProto::SharedDtor() { } } +void FileDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() { protobuf_AssignDescriptorsOnce(); return FileDescriptorProto_descriptor_; @@ -939,47 +958,50 @@ bool FileDescriptorProto::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_package; break; } // optional string package = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_package: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_package())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->package().data(), this->package().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_package: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_package())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->package().data(), this->package().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(26)) goto parse_dependency; break; } // repeated string dependency = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_dependency: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_dependency())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->dependency(0).data(), this->dependency(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_dependency: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->add_dependency())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->dependency(0).data(), this->dependency(0).length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(26)) goto parse_dependency; if (input->ExpectTag(34)) goto parse_message_type; break; @@ -987,13 +1009,14 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto message_type = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_message_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_message_type())); + } else { goto handle_uninterpreted; } - parse_message_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_message_type())); if (input->ExpectTag(34)) goto parse_message_type; if (input->ExpectTag(42)) goto parse_enum_type; break; @@ -1001,13 +1024,14 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_enum_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_enum_type())); + } else { goto handle_uninterpreted; } - parse_enum_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_enum_type())); if (input->ExpectTag(42)) goto parse_enum_type; if (input->ExpectTag(50)) goto parse_service; break; @@ -1015,13 +1039,14 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.ServiceDescriptorProto service = 6; case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_service: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_service())); + } else { goto handle_uninterpreted; } - parse_service: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_service())); if (input->ExpectTag(50)) goto parse_service; if (input->ExpectTag(58)) goto parse_extension; break; @@ -1029,13 +1054,14 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.FieldDescriptorProto extension = 7; case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extension: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension())); + } else { goto handle_uninterpreted; } - parse_extension: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_extension())); if (input->ExpectTag(58)) goto parse_extension; if (input->ExpectTag(66)) goto parse_options; break; @@ -1043,13 +1069,14 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FileOptions options = 8; case 8: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { goto handle_uninterpreted; } - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); if (input->ExpectAtEnd()) return true; break; } @@ -1072,12 +1099,6 @@ bool FileDescriptorProto::MergePartialFromCodedStream( void FileDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - FileDescriptorProto::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string name = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -1107,31 +1128,31 @@ void FileDescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.DescriptorProto message_type = 4; for (int i = 0; i < this->message_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 4, this->message_type(i), output); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; for (int i = 0; i < this->enum_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 5, this->enum_type(i), output); } // repeated .google.protobuf.ServiceDescriptorProto service = 6; for (int i = 0; i < this->service_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 6, this->service(i), output); } // repeated .google.protobuf.FieldDescriptorProto extension = 7; for (int i = 0; i < this->extension_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 7, this->extension(i), output); } // optional .google.protobuf.FileOptions options = 8; if (_has_bit(7)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 8, this->options(), output); } @@ -1284,7 +1305,9 @@ int FileDescriptorProto::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -1385,14 +1408,16 @@ const int DescriptorProto_ExtensionRange::kStartFieldNumber; const int DescriptorProto_ExtensionRange::kEndFieldNumber; #endif // !_MSC_VER -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() { +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() + : ::google::protobuf::Message() { SharedCtor(); } void DescriptorProto_ExtensionRange::InitAsDefaultInstance() { } -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) { +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -1413,6 +1438,11 @@ void DescriptorProto_ExtensionRange::SharedDtor() { } } +void DescriptorProto_ExtensionRange::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() { protobuf_AssignDescriptorsOnce(); return DescriptorProto_ExtensionRange_descriptor_; @@ -1445,27 +1475,31 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional int32 start = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &start_))); + _set_bit(0); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( - input, &start_)); - _set_bit(0); if (input->ExpectTag(16)) goto parse_end; break; } // optional int32 end = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_end: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &end_))); + _set_bit(1); + } else { goto handle_uninterpreted; } - parse_end: - DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( - input, &end_)); - _set_bit(1); if (input->ExpectAtEnd()) return true; break; } @@ -1488,12 +1522,6 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional int32 start = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); @@ -1553,7 +1581,9 @@ int DescriptorProto_ExtensionRange::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -1631,7 +1661,8 @@ const int DescriptorProto::kExtensionRangeFieldNumber; const int DescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -DescriptorProto::DescriptorProto() { +DescriptorProto::DescriptorProto() + : ::google::protobuf::Message() { SharedCtor(); } @@ -1639,7 +1670,8 @@ void DescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance()); } -DescriptorProto::DescriptorProto(const DescriptorProto& from) { +DescriptorProto::DescriptorProto(const DescriptorProto& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -1664,6 +1696,11 @@ void DescriptorProto::SharedDtor() { } } +void DescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* DescriptorProto::descriptor() { protobuf_AssignDescriptorsOnce(); return DescriptorProto_descriptor_; @@ -1707,28 +1744,30 @@ bool DescriptorProto::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_field; break; } // repeated .google.protobuf.FieldDescriptorProto field = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_field: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_field())); + } else { goto handle_uninterpreted; } - parse_field: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_field())); if (input->ExpectTag(18)) goto parse_field; if (input->ExpectTag(26)) goto parse_nested_type; break; @@ -1736,13 +1775,14 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto nested_type = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_nested_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_nested_type())); + } else { goto handle_uninterpreted; } - parse_nested_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_nested_type())); if (input->ExpectTag(26)) goto parse_nested_type; if (input->ExpectTag(34)) goto parse_enum_type; break; @@ -1750,13 +1790,14 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_enum_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_enum_type())); + } else { goto handle_uninterpreted; } - parse_enum_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_enum_type())); if (input->ExpectTag(34)) goto parse_enum_type; if (input->ExpectTag(42)) goto parse_extension_range; break; @@ -1764,13 +1805,14 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extension_range: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension_range())); + } else { goto handle_uninterpreted; } - parse_extension_range: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_extension_range())); if (input->ExpectTag(42)) goto parse_extension_range; if (input->ExpectTag(50)) goto parse_extension; break; @@ -1778,13 +1820,14 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.FieldDescriptorProto extension = 6; case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extension: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_extension())); + } else { goto handle_uninterpreted; } - parse_extension: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_extension())); if (input->ExpectTag(50)) goto parse_extension; if (input->ExpectTag(58)) goto parse_options; break; @@ -1792,13 +1835,14 @@ bool DescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.MessageOptions options = 7; case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { goto handle_uninterpreted; } - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); if (input->ExpectAtEnd()) return true; break; } @@ -1821,12 +1865,6 @@ bool DescriptorProto::MergePartialFromCodedStream( void DescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - DescriptorProto::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string name = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -1838,37 +1876,37 @@ void DescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.FieldDescriptorProto field = 2; for (int i = 0; i < this->field_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->field(i), output); } // repeated .google.protobuf.DescriptorProto nested_type = 3; for (int i = 0; i < this->nested_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->nested_type(i), output); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; for (int i = 0; i < this->enum_type_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 4, this->enum_type(i), output); } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; for (int i = 0; i < this->extension_range_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 5, this->extension_range(i), output); } // repeated .google.protobuf.FieldDescriptorProto extension = 6; for (int i = 0; i < this->extension_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 6, this->extension(i), output); } // optional .google.protobuf.MessageOptions options = 7; if (_has_bit(6)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 7, this->options(), output); } @@ -2003,7 +2041,9 @@ int DescriptorProto::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -2146,6 +2186,7 @@ const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32; const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64; const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN; const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX; +const int FieldDescriptorProto::Type_ARRAYSIZE; #endif // _MSC_VER const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() { protobuf_AssignDescriptorsOnce(); @@ -2168,6 +2209,7 @@ const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED; const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED; const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN; const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX; +const int FieldDescriptorProto::Label_ARRAYSIZE; #endif // _MSC_VER const ::std::string FieldDescriptorProto::_default_name_; const ::std::string FieldDescriptorProto::_default_type_name_; @@ -2184,7 +2226,8 @@ const int FieldDescriptorProto::kDefaultValueFieldNumber; const int FieldDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -FieldDescriptorProto::FieldDescriptorProto() { +FieldDescriptorProto::FieldDescriptorProto() + : ::google::protobuf::Message() { SharedCtor(); } @@ -2192,7 +2235,8 @@ void FieldDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance()); } -FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) { +FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -2232,6 +2276,11 @@ void FieldDescriptorProto::SharedDtor() { } } +void FieldDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() { protobuf_AssignDescriptorsOnce(); return FieldDescriptorProto_descriptor_; @@ -2288,62 +2337,69 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_extendee; break; } // optional string extendee = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extendee: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_extendee())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extendee().data(), this->extendee().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_extendee: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_extendee())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->extendee().data(), this->extendee().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(24)) goto parse_number; break; } // optional int32 number = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &number_))); + _set_bit(1); + } else { goto handle_uninterpreted; } - parse_number: - DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( - input, &number_)); - _set_bit(1); if (input->ExpectTag(32)) goto parse_label; break; } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_label: - int value; - DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); - if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) { - set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value)); + parse_label: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) { + set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value)); + } else { + mutable_unknown_fields()->AddVarint(4, value); + } } else { - mutable_unknown_fields()->AddVarint(4, value); + goto handle_uninterpreted; } if (input->ExpectTag(40)) goto parse_type; break; @@ -2351,17 +2407,20 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FieldDescriptorProto.Type type = 5; case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_type: - int value; - DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); - if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) { - set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value)); + parse_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) { + set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value)); + } else { + mutable_unknown_fields()->AddVarint(5, value); + } } else { - mutable_unknown_fields()->AddVarint(5, value); + goto handle_uninterpreted; } if (input->ExpectTag(50)) goto parse_type_name; break; @@ -2369,45 +2428,48 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional string type_name = 6; case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_type_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_type_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->type_name().data(), this->type_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_type_name: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_type_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->type_name().data(), this->type_name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(58)) goto parse_default_value; break; } // optional string default_value = 7; case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_default_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_default_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->default_value().data(), this->default_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_default_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_default_value())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->default_value().data(), this->default_value().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(66)) goto parse_options; break; } // optional .google.protobuf.FieldOptions options = 8; case 8: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { goto handle_uninterpreted; } - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); if (input->ExpectAtEnd()) return true; break; } @@ -2430,12 +2492,6 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( void FieldDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - FieldDescriptorProto::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string name = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -2491,7 +2547,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( // optional .google.protobuf.FieldOptions options = 8; if (_has_bit(7)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 8, this->options(), output); } @@ -2638,7 +2694,9 @@ int FieldDescriptorProto::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -2739,7 +2797,8 @@ const int EnumDescriptorProto::kValueFieldNumber; const int EnumDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -EnumDescriptorProto::EnumDescriptorProto() { +EnumDescriptorProto::EnumDescriptorProto() + : ::google::protobuf::Message() { SharedCtor(); } @@ -2747,7 +2806,8 @@ void EnumDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance()); } -EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) { +EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -2772,6 +2832,11 @@ void EnumDescriptorProto::SharedDtor() { } } +void EnumDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() { protobuf_AssignDescriptorsOnce(); return EnumDescriptorProto_descriptor_; @@ -2811,28 +2876,30 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_value; break; } // repeated .google.protobuf.EnumValueDescriptorProto value = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_value())); + } else { goto handle_uninterpreted; } - parse_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_value())); if (input->ExpectTag(18)) goto parse_value; if (input->ExpectTag(26)) goto parse_options; break; @@ -2840,13 +2907,14 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.EnumOptions options = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { goto handle_uninterpreted; } - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); if (input->ExpectAtEnd()) return true; break; } @@ -2869,12 +2937,6 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( void EnumDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - EnumDescriptorProto::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string name = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -2886,13 +2948,13 @@ void EnumDescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.EnumValueDescriptorProto value = 2; for (int i = 0; i < this->value_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->value(i), output); } // optional .google.protobuf.EnumOptions options = 3; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->options(), output); } @@ -2967,7 +3029,9 @@ int EnumDescriptorProto::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -3049,7 +3113,8 @@ const int EnumValueDescriptorProto::kNumberFieldNumber; const int EnumValueDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -EnumValueDescriptorProto::EnumValueDescriptorProto() { +EnumValueDescriptorProto::EnumValueDescriptorProto() + : ::google::protobuf::Message() { SharedCtor(); } @@ -3057,7 +3122,8 @@ void EnumValueDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance()); } -EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) { +EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -3083,6 +3149,11 @@ void EnumValueDescriptorProto::SharedDtor() { } } +void EnumValueDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() { protobuf_AssignDescriptorsOnce(); return EnumValueDescriptorProto_descriptor_; @@ -3122,42 +3193,46 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(16)) goto parse_number; break; } // optional int32 number = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &number_))); + _set_bit(1); + } else { goto handle_uninterpreted; } - parse_number: - DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( - input, &number_)); - _set_bit(1); if (input->ExpectTag(26)) goto parse_options; break; } // optional .google.protobuf.EnumValueOptions options = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { goto handle_uninterpreted; } - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); if (input->ExpectAtEnd()) return true; break; } @@ -3180,12 +3255,6 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( void EnumValueDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - EnumValueDescriptorProto::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string name = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -3202,7 +3271,7 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( // optional .google.protobuf.EnumValueOptions options = 3; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->options(), output); } @@ -3274,7 +3343,9 @@ int EnumValueDescriptorProto::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -3355,7 +3426,8 @@ const int ServiceDescriptorProto::kMethodFieldNumber; const int ServiceDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -ServiceDescriptorProto::ServiceDescriptorProto() { +ServiceDescriptorProto::ServiceDescriptorProto() + : ::google::protobuf::Message() { SharedCtor(); } @@ -3363,7 +3435,8 @@ void ServiceDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance()); } -ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) { +ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -3388,6 +3461,11 @@ void ServiceDescriptorProto::SharedDtor() { } } +void ServiceDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() { protobuf_AssignDescriptorsOnce(); return ServiceDescriptorProto_descriptor_; @@ -3427,28 +3505,30 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_method; break; } // repeated .google.protobuf.MethodDescriptorProto method = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_method: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_method())); + } else { goto handle_uninterpreted; } - parse_method: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_method())); if (input->ExpectTag(18)) goto parse_method; if (input->ExpectTag(26)) goto parse_options; break; @@ -3456,13 +3536,14 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.ServiceOptions options = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { goto handle_uninterpreted; } - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); if (input->ExpectAtEnd()) return true; break; } @@ -3485,12 +3566,6 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( void ServiceDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - ServiceDescriptorProto::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string name = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -3502,13 +3577,13 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( // repeated .google.protobuf.MethodDescriptorProto method = 2; for (int i = 0; i < this->method_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->method(i), output); } // optional .google.protobuf.ServiceOptions options = 3; if (_has_bit(2)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->options(), output); } @@ -3583,7 +3658,9 @@ int ServiceDescriptorProto::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -3668,7 +3745,8 @@ const int MethodDescriptorProto::kOutputTypeFieldNumber; const int MethodDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER -MethodDescriptorProto::MethodDescriptorProto() { +MethodDescriptorProto::MethodDescriptorProto() + : ::google::protobuf::Message() { SharedCtor(); } @@ -3676,7 +3754,8 @@ void MethodDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance()); } -MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) { +MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -3709,6 +3788,11 @@ void MethodDescriptorProto::SharedDtor() { } } +void MethodDescriptorProto::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() { protobuf_AssignDescriptorsOnce(); return MethodDescriptorProto_descriptor_; @@ -3757,60 +3841,64 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string name = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(18)) goto parse_input_type; break; } // optional string input_type = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_input_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_input_type())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->input_type().data(), this->input_type().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_input_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_input_type())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->input_type().data(), this->input_type().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(26)) goto parse_output_type; break; } // optional string output_type = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_output_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_output_type())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->output_type().data(), this->output_type().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_output_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_output_type())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->output_type().data(), this->output_type().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(34)) goto parse_options; break; } // optional .google.protobuf.MethodOptions options = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { goto handle_uninterpreted; } - parse_options: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_options())); if (input->ExpectAtEnd()) return true; break; } @@ -3833,12 +3921,6 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( void MethodDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - MethodDescriptorProto::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string name = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -3868,7 +3950,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( // optional .google.protobuf.MethodOptions options = 4; if (_has_bit(3)) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 4, this->options(), output); } @@ -3962,7 +4044,9 @@ int MethodDescriptorProto::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -4061,6 +4145,7 @@ const FileOptions_OptimizeMode FileOptions::CODE_SIZE; const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME; const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN; const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX; +const int FileOptions::OptimizeMode_ARRAYSIZE; #endif // _MSC_VER const ::std::string FileOptions::_default_java_package_; const ::std::string FileOptions::_default_java_outer_classname_; @@ -4069,17 +4154,22 @@ const int FileOptions::kJavaPackageFieldNumber; const int FileOptions::kJavaOuterClassnameFieldNumber; const int FileOptions::kJavaMultipleFilesFieldNumber; const int FileOptions::kOptimizeForFieldNumber; +const int FileOptions::kCcGenericServicesFieldNumber; +const int FileOptions::kJavaGenericServicesFieldNumber; +const int FileOptions::kPyGenericServicesFieldNumber; const int FileOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -FileOptions::FileOptions() { +FileOptions::FileOptions() + : ::google::protobuf::Message() { SharedCtor(); } void FileOptions::InitAsDefaultInstance() { } -FileOptions::FileOptions(const FileOptions& from) { +FileOptions::FileOptions(const FileOptions& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -4090,6 +4180,9 @@ void FileOptions::SharedCtor() { java_outer_classname_ = const_cast< ::std::string*>(&_default_java_outer_classname_); java_multiple_files_ = false; optimize_for_ = 1; + cc_generic_services_ = true; + java_generic_services_ = true; + py_generic_services_ = true; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -4108,6 +4201,11 @@ void FileOptions::SharedDtor() { } } +void FileOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* FileOptions::descriptor() { protobuf_AssignDescriptorsOnce(); return FileOptions_descriptor_; @@ -4138,6 +4236,9 @@ void FileOptions::Clear() { } java_multiple_files_ = false; optimize_for_ = 1; + cc_generic_services_ = true; + java_generic_services_ = true; + py_generic_services_ = true; } uninterpreted_option_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); @@ -4152,48 +4253,53 @@ bool FileOptions::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional string java_package = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_java_package())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_package().data(), this->java_package().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_java_package())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_package().data(), this->java_package().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(66)) goto parse_java_outer_classname; break; } // optional string java_outer_classname = 8; case 8: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_java_outer_classname: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_java_outer_classname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->java_outer_classname().data(), this->java_outer_classname().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_java_outer_classname: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_java_outer_classname())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->java_outer_classname().data(), this->java_outer_classname().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(72)) goto parse_optimize_for; break; } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; case 9: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_optimize_for: - int value; - DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); - if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) { - set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value)); + parse_optimize_for: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) { + set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value)); + } else { + mutable_unknown_fields()->AddVarint(9, value); + } } else { - mutable_unknown_fields()->AddVarint(9, value); + goto handle_uninterpreted; } if (input->ExpectTag(80)) goto parse_java_multiple_files; break; @@ -4201,27 +4307,78 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool java_multiple_files = 10 [default = false]; case 10: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_java_multiple_files: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &java_multiple_files_))); + _set_bit(2); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(128)) goto parse_cc_generic_services; + break; + } + + // optional bool cc_generic_services = 16 [default = true]; + case 16: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_cc_generic_services: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &cc_generic_services_))); + _set_bit(4); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(136)) goto parse_java_generic_services; + break; + } + + // optional bool java_generic_services = 17 [default = true]; + case 17: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_java_generic_services: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &java_generic_services_))); + _set_bit(5); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(144)) goto parse_py_generic_services; + break; + } + + // optional bool py_generic_services = 18 [default = true]; + case 18: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_py_generic_services: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &py_generic_services_))); + _set_bit(6); + } else { goto handle_uninterpreted; } - parse_java_multiple_files: - DO_(::google::protobuf::internal::WireFormatLite::ReadBool( - input, &java_multiple_files_)); - _set_bit(2); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; break; } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { goto handle_uninterpreted; } - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -4250,12 +4407,6 @@ bool FileOptions::MergePartialFromCodedStream( void FileOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - FileOptions::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional string java_package = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -4285,9 +4436,24 @@ void FileOptions::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output); } + // optional bool cc_generic_services = 16 [default = true]; + if (_has_bit(4)) { + ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output); + } + + // optional bool java_generic_services = 17 [default = true]; + if (_has_bit(5)) { + ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output); + } + + // optional bool py_generic_services = 18 [default = true]; + if (_has_bit(6)) { + ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 999, this->uninterpreted_option(i), output); } @@ -4334,6 +4500,21 @@ void FileOptions::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target); } + // optional bool cc_generic_services = 16 [default = true]; + if (_has_bit(4)) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target); + } + + // optional bool java_generic_services = 17 [default = true]; + if (_has_bit(5)) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target); + } + + // optional bool py_generic_services = 18 [default = true]; + if (_has_bit(6)) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: @@ -4381,6 +4562,21 @@ int FileOptions::ByteSize() const { ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for()); } + // optional bool cc_generic_services = 16 [default = true]; + if (has_cc_generic_services()) { + total_size += 2 + 1; + } + + // optional bool java_generic_services = 17 [default = true]; + if (has_java_generic_services()) { + total_size += 2 + 1; + } + + // optional bool py_generic_services = 18 [default = true]; + if (has_py_generic_services()) { + total_size += 2 + 1; + } + } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; total_size += 2 * this->uninterpreted_option_size(); @@ -4397,7 +4593,9 @@ int FileOptions::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -4429,6 +4627,15 @@ void FileOptions::MergeFrom(const FileOptions& from) { if (from._has_bit(3)) { set_optimize_for(from.optimize_for()); } + if (from._has_bit(4)) { + set_cc_generic_services(from.cc_generic_services()); + } + if (from._has_bit(5)) { + set_java_generic_services(from.java_generic_services()); + } + if (from._has_bit(6)) { + set_py_generic_services(from.py_generic_services()); + } } _extensions_.MergeFrom(from._extensions_); mutable_unknown_fields()->MergeFrom(from.unknown_fields()); @@ -4461,6 +4668,9 @@ void FileOptions::Swap(FileOptions* other) { std::swap(java_outer_classname_, other->java_outer_classname_); std::swap(java_multiple_files_, other->java_multiple_files_); std::swap(optimize_for_, other->optimize_for_); + std::swap(cc_generic_services_, other->cc_generic_services_); + std::swap(java_generic_services_, other->java_generic_services_); + std::swap(py_generic_services_, other->py_generic_services_); uninterpreted_option_.Swap(&other->uninterpreted_option_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); @@ -4486,14 +4696,16 @@ const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber; const int MessageOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -MessageOptions::MessageOptions() { +MessageOptions::MessageOptions() + : ::google::protobuf::Message() { SharedCtor(); } void MessageOptions::InitAsDefaultInstance() { } -MessageOptions::MessageOptions(const MessageOptions& from) { +MessageOptions::MessageOptions(const MessageOptions& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -4514,6 +4726,11 @@ void MessageOptions::SharedDtor() { } } +void MessageOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* MessageOptions::descriptor() { protobuf_AssignDescriptorsOnce(); return MessageOptions_descriptor_; @@ -4548,40 +4765,45 @@ bool MessageOptions::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional bool message_set_wire_format = 1 [default = false]; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &message_set_wire_format_))); + _set_bit(0); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadBool( - input, &message_set_wire_format_)); - _set_bit(0); if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor; break; } // optional bool no_standard_descriptor_accessor = 2 [default = false]; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_no_standard_descriptor_accessor: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &no_standard_descriptor_accessor_))); + _set_bit(1); + } else { goto handle_uninterpreted; } - parse_no_standard_descriptor_accessor: - DO_(::google::protobuf::internal::WireFormatLite::ReadBool( - input, &no_standard_descriptor_accessor_)); - _set_bit(1); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; break; } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { goto handle_uninterpreted; } - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -4610,12 +4832,6 @@ bool MessageOptions::MergePartialFromCodedStream( void MessageOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - MessageOptions::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // optional bool message_set_wire_format = 1 [default = false]; if (_has_bit(0)) { ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output); @@ -4628,7 +4844,7 @@ void MessageOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 999, this->uninterpreted_option(i), output); } @@ -4702,7 +4918,9 @@ int MessageOptions::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -4783,6 +5001,7 @@ const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() { } bool FieldOptions_CType_IsValid(int value) { switch(value) { + case 0: case 1: case 2: return true; @@ -4792,10 +5011,12 @@ bool FieldOptions_CType_IsValid(int value) { } #ifndef _MSC_VER +const FieldOptions_CType FieldOptions::STRING; const FieldOptions_CType FieldOptions::CORD; const FieldOptions_CType FieldOptions::STRING_PIECE; const FieldOptions_CType FieldOptions::CType_MIN; const FieldOptions_CType FieldOptions::CType_MAX; +const int FieldOptions::CType_ARRAYSIZE; #endif // _MSC_VER const ::std::string FieldOptions::_default_experimental_map_key_; #ifndef _MSC_VER @@ -4806,21 +5027,23 @@ const int FieldOptions::kExperimentalMapKeyFieldNumber; const int FieldOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -FieldOptions::FieldOptions() { +FieldOptions::FieldOptions() + : ::google::protobuf::Message() { SharedCtor(); } void FieldOptions::InitAsDefaultInstance() { } -FieldOptions::FieldOptions(const FieldOptions& from) { +FieldOptions::FieldOptions(const FieldOptions& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } void FieldOptions::SharedCtor() { _cached_size_ = 0; - ctype_ = 1; + ctype_ = 0; packed_ = false; deprecated_ = false; experimental_map_key_ = const_cast< ::std::string*>(&_default_experimental_map_key_); @@ -4839,6 +5062,11 @@ void FieldOptions::SharedDtor() { } } +void FieldOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* FieldOptions::descriptor() { protobuf_AssignDescriptorsOnce(); return FieldOptions_descriptor_; @@ -4857,7 +5085,7 @@ FieldOptions* FieldOptions::New() const { void FieldOptions::Clear() { _extensions_.Clear(); if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - ctype_ = 1; + ctype_ = 0; packed_ = false; deprecated_ = false; if (_has_bit(3)) { @@ -4877,18 +5105,21 @@ bool FieldOptions::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional .google.protobuf.FieldOptions.CType ctype = 1; + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - int value; - DO_(::google::protobuf::internal::WireFormatLite::ReadEnum(input, &value)); - if (::google::protobuf::FieldOptions_CType_IsValid(value)) { - set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value)); + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FieldOptions_CType_IsValid(value)) { + set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } } else { - mutable_unknown_fields()->AddVarint(1, value); + goto handle_uninterpreted; } if (input->ExpectTag(16)) goto parse_packed; break; @@ -4896,57 +5127,63 @@ bool FieldOptions::MergePartialFromCodedStream( // optional bool packed = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_packed: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &packed_))); + _set_bit(1); + } else { goto handle_uninterpreted; } - parse_packed: - DO_(::google::protobuf::internal::WireFormatLite::ReadBool( - input, &packed_)); - _set_bit(1); if (input->ExpectTag(24)) goto parse_deprecated; break; } // optional bool deprecated = 3 [default = false]; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_deprecated: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &deprecated_))); + _set_bit(2); + } else { goto handle_uninterpreted; } - parse_deprecated: - DO_(::google::protobuf::internal::WireFormatLite::ReadBool( - input, &deprecated_)); - _set_bit(2); if (input->ExpectTag(74)) goto parse_experimental_map_key; break; } // optional string experimental_map_key = 9; case 9: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_experimental_map_key: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_experimental_map_key())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->experimental_map_key().data(), this->experimental_map_key().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_experimental_map_key: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_experimental_map_key())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->experimental_map_key().data(), this->experimental_map_key().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; break; } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { goto handle_uninterpreted; } - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -4975,13 +5212,7 @@ bool FieldOptions::MergePartialFromCodedStream( void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - FieldOptions::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - - // optional .google.protobuf.FieldOptions.CType ctype = 1; + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; if (_has_bit(0)) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->ctype(), output); @@ -5008,7 +5239,7 @@ void FieldOptions::SerializeWithCachedSizes( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 999, this->uninterpreted_option(i), output); } @@ -5024,7 +5255,7 @@ void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // optional .google.protobuf.FieldOptions.CType ctype = 1; + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; if (_has_bit(0)) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 1, this->ctype(), target); @@ -5072,7 +5303,7 @@ int FieldOptions::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional .google.protobuf.FieldOptions.CType ctype = 1; + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; if (has_ctype()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype()); @@ -5111,7 +5342,9 @@ int FieldOptions::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -5198,14 +5431,16 @@ void FieldOptions::Swap(FieldOptions* other) { const int EnumOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -EnumOptions::EnumOptions() { +EnumOptions::EnumOptions() + : ::google::protobuf::Message() { SharedCtor(); } void EnumOptions::InitAsDefaultInstance() { } -EnumOptions::EnumOptions(const EnumOptions& from) { +EnumOptions::EnumOptions(const EnumOptions& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -5224,6 +5459,11 @@ void EnumOptions::SharedDtor() { } } +void EnumOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* EnumOptions::descriptor() { protobuf_AssignDescriptorsOnce(); return EnumOptions_descriptor_; @@ -5254,13 +5494,14 @@ bool EnumOptions::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { goto handle_uninterpreted; } - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -5289,15 +5530,9 @@ bool EnumOptions::MergePartialFromCodedStream( void EnumOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - EnumOptions::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 999, this->uninterpreted_option(i), output); } @@ -5349,7 +5584,9 @@ int EnumOptions::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -5418,14 +5655,16 @@ void EnumOptions::Swap(EnumOptions* other) { const int EnumValueOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -EnumValueOptions::EnumValueOptions() { +EnumValueOptions::EnumValueOptions() + : ::google::protobuf::Message() { SharedCtor(); } void EnumValueOptions::InitAsDefaultInstance() { } -EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) { +EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -5444,6 +5683,11 @@ void EnumValueOptions::SharedDtor() { } } +void EnumValueOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() { protobuf_AssignDescriptorsOnce(); return EnumValueOptions_descriptor_; @@ -5474,13 +5718,14 @@ bool EnumValueOptions::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { goto handle_uninterpreted; } - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -5509,15 +5754,9 @@ bool EnumValueOptions::MergePartialFromCodedStream( void EnumValueOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - EnumValueOptions::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 999, this->uninterpreted_option(i), output); } @@ -5569,7 +5808,9 @@ int EnumValueOptions::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -5638,14 +5879,16 @@ void EnumValueOptions::Swap(EnumValueOptions* other) { const int ServiceOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -ServiceOptions::ServiceOptions() { +ServiceOptions::ServiceOptions() + : ::google::protobuf::Message() { SharedCtor(); } void ServiceOptions::InitAsDefaultInstance() { } -ServiceOptions::ServiceOptions(const ServiceOptions& from) { +ServiceOptions::ServiceOptions(const ServiceOptions& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -5664,6 +5907,11 @@ void ServiceOptions::SharedDtor() { } } +void ServiceOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* ServiceOptions::descriptor() { protobuf_AssignDescriptorsOnce(); return ServiceOptions_descriptor_; @@ -5694,13 +5942,14 @@ bool ServiceOptions::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { goto handle_uninterpreted; } - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -5729,15 +5978,9 @@ bool ServiceOptions::MergePartialFromCodedStream( void ServiceOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - ServiceOptions::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 999, this->uninterpreted_option(i), output); } @@ -5789,7 +6032,9 @@ int ServiceOptions::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -5858,14 +6103,16 @@ void ServiceOptions::Swap(ServiceOptions* other) { const int MethodOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER -MethodOptions::MethodOptions() { +MethodOptions::MethodOptions() + : ::google::protobuf::Message() { SharedCtor(); } void MethodOptions::InitAsDefaultInstance() { } -MethodOptions::MethodOptions(const MethodOptions& from) { +MethodOptions::MethodOptions(const MethodOptions& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -5884,6 +6131,11 @@ void MethodOptions::SharedDtor() { } } +void MethodOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* MethodOptions::descriptor() { protobuf_AssignDescriptorsOnce(); return MethodOptions_descriptor_; @@ -5914,13 +6166,14 @@ bool MethodOptions::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { goto handle_uninterpreted; } - parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_uninterpreted_option())); if (input->ExpectTag(7994)) goto parse_uninterpreted_option; if (input->ExpectAtEnd()) return true; break; @@ -5949,15 +6202,9 @@ bool MethodOptions::MergePartialFromCodedStream( void MethodOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - MethodOptions::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 999, this->uninterpreted_option(i), output); } @@ -6009,7 +6256,9 @@ int MethodOptions::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -6080,14 +6329,16 @@ const int UninterpretedOption_NamePart::kNamePartFieldNumber; const int UninterpretedOption_NamePart::kIsExtensionFieldNumber; #endif // !_MSC_VER -UninterpretedOption_NamePart::UninterpretedOption_NamePart() { +UninterpretedOption_NamePart::UninterpretedOption_NamePart() + : ::google::protobuf::Message() { SharedCtor(); } void UninterpretedOption_NamePart::InitAsDefaultInstance() { } -UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) { +UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -6111,6 +6362,11 @@ void UninterpretedOption_NamePart::SharedDtor() { } } +void UninterpretedOption_NamePart::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() { protobuf_AssignDescriptorsOnce(); return UninterpretedOption_NamePart_descriptor_; @@ -6147,29 +6403,32 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // required string name_part = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name_part())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name_part().data(), this->name_part().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name_part())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->name_part().data(), this->name_part().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(16)) goto parse_is_extension; break; } // required bool is_extension = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_is_extension: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &is_extension_))); + _set_bit(1); + } else { goto handle_uninterpreted; } - parse_is_extension: - DO_(::google::protobuf::internal::WireFormatLite::ReadBool( - input, &is_extension_)); - _set_bit(1); if (input->ExpectAtEnd()) return true; break; } @@ -6192,12 +6451,6 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( void UninterpretedOption_NamePart::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // required string name_part = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( @@ -6264,7 +6517,9 @@ int UninterpretedOption_NamePart::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -6343,14 +6598,16 @@ const int UninterpretedOption::kDoubleValueFieldNumber; const int UninterpretedOption::kStringValueFieldNumber; #endif // !_MSC_VER -UninterpretedOption::UninterpretedOption() { +UninterpretedOption::UninterpretedOption() + : ::google::protobuf::Message() { SharedCtor(); } void UninterpretedOption::InitAsDefaultInstance() { } -UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) { +UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) + : ::google::protobuf::Message() { SharedCtor(); MergeFrom(from); } @@ -6380,6 +6637,11 @@ void UninterpretedOption::SharedDtor() { } } +void UninterpretedOption::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() { protobuf_AssignDescriptorsOnce(); return UninterpretedOption_descriptor_; @@ -6424,13 +6686,14 @@ bool UninterpretedOption::MergePartialFromCodedStream( switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_name())); + } else { goto handle_uninterpreted; } - parse_name: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_name())); if (input->ExpectTag(18)) goto parse_name; if (input->ExpectTag(26)) goto parse_identifier_value; break; @@ -6438,71 +6701,79 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional string identifier_value = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_identifier_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_identifier_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->identifier_value().data(), this->identifier_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { goto handle_uninterpreted; } - parse_identifier_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_identifier_value())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->identifier_value().data(), this->identifier_value().length(), - ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(32)) goto parse_positive_int_value; break; } // optional uint64 positive_int_value = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_positive_int_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &positive_int_value_))); + _set_bit(2); + } else { goto handle_uninterpreted; } - parse_positive_int_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadUInt64( - input, &positive_int_value_)); - _set_bit(2); if (input->ExpectTag(40)) goto parse_negative_int_value; break; } // optional int64 negative_int_value = 5; case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_negative_int_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &negative_int_value_))); + _set_bit(3); + } else { goto handle_uninterpreted; } - parse_negative_int_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadInt64( - input, &negative_int_value_)); - _set_bit(3); if (input->ExpectTag(49)) goto parse_double_value; break; } // optional double double_value = 6; case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) { + parse_double_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &double_value_))); + _set_bit(4); + } else { goto handle_uninterpreted; } - parse_double_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadDouble( - input, &double_value_)); - _set_bit(4); if (input->ExpectTag(58)) goto parse_string_value; break; } // optional bytes string_value = 7; case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) != + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_string_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_string_value())); + } else { goto handle_uninterpreted; } - parse_string_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( - input, this->mutable_string_value())); if (input->ExpectAtEnd()) return true; break; } @@ -6525,15 +6796,9 @@ bool UninterpretedOption::MergePartialFromCodedStream( void UninterpretedOption::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNBytesAndAdvance(_cached_size_); - if (raw_buffer != NULL) { - UninterpretedOption::SerializeWithCachedSizesToArray(raw_buffer); - return; - } - // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; for (int i = 0; i < this->name_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageNoVirtual( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->name(i), output); } @@ -6672,7 +6937,9 @@ int UninterpretedOption::ByteSize() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( unknown_fields()); } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); return total_size; } @@ -6754,5 +7021,9 @@ void UninterpretedOption::Swap(UninterpretedOption* other) { } +// @@protoc_insertion_point(namespace_scope) + } // namespace protobuf } // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index bc4ec31..2743b6f 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -1,4 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/descriptor.proto #ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED #define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED @@ -7,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 2002000 +#if GOOGLE_PROTOBUF_VERSION < 2003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 2002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -22,6 +23,7 @@ #include <google/protobuf/repeated_field.h> #include <google/protobuf/extension_set.h> #include <google/protobuf/generated_message_reflection.h> +// @@protoc_insertion_point(includes) namespace google { namespace protobuf { @@ -73,6 +75,7 @@ enum FieldDescriptorProto_Type { LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value); const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE; const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64; +const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1; LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) { @@ -92,6 +95,7 @@ enum FieldDescriptorProto_Label { LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value); const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL; const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED; +const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1; LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) { @@ -111,6 +115,7 @@ enum FileOptions_OptimizeMode { LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value); const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED; const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME; +const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1; LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) { @@ -123,12 +128,14 @@ inline bool FileOptions_OptimizeMode_Parse( FileOptions_OptimizeMode_descriptor(), name, value); } enum FieldOptions_CType { + FieldOptions_CType_STRING = 0, FieldOptions_CType_CORD = 1, FieldOptions_CType_STRING_PIECE = 2 }; LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value); -const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_CORD; +const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING; const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE; +const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1; LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor(); inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) { @@ -164,6 +171,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message static const ::google::protobuf::Descriptor* descriptor(); static const FileDescriptorSet& default_instance(); + void Swap(FileDescriptorSet* other); // implements Message ---------------------------------------------- @@ -186,7 +194,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -199,12 +207,15 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message inline int file_size() const; inline void clear_file(); static const int kFileFieldNumber = 1; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& file() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* mutable_file(); inline const ::google::protobuf::FileDescriptorProto& file(int index) const; inline ::google::protobuf::FileDescriptorProto* mutable_file(int index); inline ::google::protobuf::FileDescriptorProto* add_file(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + file() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + mutable_file(); + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -254,6 +265,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag static const ::google::protobuf::Descriptor* descriptor(); static const FileDescriptorProto& default_instance(); + void Swap(FileDescriptorProto* other); // implements Message ---------------------------------------------- @@ -276,7 +288,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -309,8 +321,6 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag inline int dependency_size() const; inline void clear_dependency(); static const int kDependencyFieldNumber = 3; - inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const; - inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency(); inline const ::std::string& dependency(int index) const; inline ::std::string* mutable_dependency(int index); inline void set_dependency(int index, const ::std::string& value); @@ -320,46 +330,56 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag inline void add_dependency(const ::std::string& value); inline void add_dependency(const char* value); inline void add_dependency(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency(); // repeated .google.protobuf.DescriptorProto message_type = 4; inline int message_type_size() const; inline void clear_message_type(); static const int kMessageTypeFieldNumber = 4; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& message_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* mutable_message_type(); inline const ::google::protobuf::DescriptorProto& message_type(int index) const; inline ::google::protobuf::DescriptorProto* mutable_message_type(int index); inline ::google::protobuf::DescriptorProto* add_message_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& + message_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* + mutable_message_type(); // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; inline int enum_type_size() const; inline void clear_enum_type(); static const int kEnumTypeFieldNumber = 5; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& enum_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* mutable_enum_type(); inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& + enum_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* + mutable_enum_type(); // repeated .google.protobuf.ServiceDescriptorProto service = 6; inline int service_size() const; inline void clear_service(); static const int kServiceFieldNumber = 6; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& service() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* mutable_service(); inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const; inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index); inline ::google::protobuf::ServiceDescriptorProto* add_service(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& + service() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* + mutable_service(); // repeated .google.protobuf.FieldDescriptorProto extension = 7; inline int extension_size() const; inline void clear_extension(); static const int kExtensionFieldNumber = 7; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& extension() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_extension(); inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); inline ::google::protobuf::FieldDescriptorProto* add_extension(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + extension() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_extension(); // optional .google.protobuf.FileOptions options = 8; inline bool has_options() const; @@ -368,6 +388,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag inline const ::google::protobuf::FileOptions& options() const; inline ::google::protobuf::FileOptions* mutable_options(); + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -426,6 +447,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto static const ::google::protobuf::Descriptor* descriptor(); static const DescriptorProto_ExtensionRange& default_instance(); + void Swap(DescriptorProto_ExtensionRange* other); // implements Message ---------------------------------------------- @@ -448,7 +470,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -471,6 +493,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto inline ::google::protobuf::int32 end() const; inline void set_end(::google::protobuf::int32 value); + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -521,6 +544,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const DescriptorProto& default_instance(); + void Swap(DescriptorProto* other); // implements Message ---------------------------------------------- @@ -543,7 +567,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -568,51 +592,61 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { inline int field_size() const; inline void clear_field(); static const int kFieldFieldNumber = 2; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& field() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_field(); inline const ::google::protobuf::FieldDescriptorProto& field(int index) const; inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index); inline ::google::protobuf::FieldDescriptorProto* add_field(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + field() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_field(); // repeated .google.protobuf.FieldDescriptorProto extension = 6; inline int extension_size() const; inline void clear_extension(); static const int kExtensionFieldNumber = 6; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& extension() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_extension(); inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); inline ::google::protobuf::FieldDescriptorProto* add_extension(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + extension() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_extension(); // repeated .google.protobuf.DescriptorProto nested_type = 3; inline int nested_type_size() const; inline void clear_nested_type(); static const int kNestedTypeFieldNumber = 3; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& nested_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* mutable_nested_type(); inline const ::google::protobuf::DescriptorProto& nested_type(int index) const; inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index); inline ::google::protobuf::DescriptorProto* add_nested_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& + nested_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* + mutable_nested_type(); // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; inline int enum_type_size() const; inline void clear_enum_type(); static const int kEnumTypeFieldNumber = 4; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& enum_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* mutable_enum_type(); inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& + enum_type() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* + mutable_enum_type(); // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; inline int extension_range_size() const; inline void clear_extension_range(); static const int kExtensionRangeFieldNumber = 5; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& extension_range() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* mutable_extension_range(); inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const; inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index); inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& + extension_range() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* + mutable_extension_range(); // optional .google.protobuf.MessageOptions options = 7; inline bool has_options() const; @@ -621,6 +655,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { inline const ::google::protobuf::MessageOptions& options() const; inline ::google::protobuf::MessageOptions* mutable_options(); + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -677,6 +712,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa static const ::google::protobuf::Descriptor* descriptor(); static const FieldDescriptorProto& default_instance(); + void Swap(FieldDescriptorProto* other); // implements Message ---------------------------------------------- @@ -699,7 +735,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -732,6 +768,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa FieldDescriptorProto_Type_Type_MIN; static const Type Type_MAX = FieldDescriptorProto_Type_Type_MAX; + static const int Type_ARRAYSIZE = + FieldDescriptorProto_Type_Type_ARRAYSIZE; static inline const ::google::protobuf::EnumDescriptor* Type_descriptor() { return FieldDescriptorProto_Type_descriptor(); @@ -755,6 +793,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa FieldDescriptorProto_Label_Label_MIN; static const Label Label_MAX = FieldDescriptorProto_Label_Label_MAX; + static const int Label_ARRAYSIZE = + FieldDescriptorProto_Label_Label_ARRAYSIZE; static inline const ::google::protobuf::EnumDescriptor* Label_descriptor() { return FieldDescriptorProto_Label_descriptor(); @@ -837,6 +877,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa inline const ::google::protobuf::FieldOptions& options() const; inline ::google::protobuf::FieldOptions* mutable_options(); + // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -897,6 +938,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag static const ::google::protobuf::Descriptor* descriptor(); static const EnumDescriptorProto& default_instance(); + void Swap(EnumDescriptorProto* other); // implements Message ---------------------------------------------- @@ -919,7 +961,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -942,11 +984,13 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag inline int value_size() const; inline void clear_value(); static const int kValueFieldNumber = 2; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& value() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* mutable_value(); inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const; inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index); inline ::google::protobuf::EnumValueDescriptorProto* add_value(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& + value() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* + mutable_value(); // optional .google.protobuf.EnumOptions options = 3; inline bool has_options() const; @@ -955,6 +999,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag inline const ::google::protobuf::EnumOptions& options() const; inline ::google::protobuf::EnumOptions* mutable_options(); + // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -1007,6 +1052,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M static const ::google::protobuf::Descriptor* descriptor(); static const EnumValueDescriptorProto& default_instance(); + void Swap(EnumValueDescriptorProto* other); // implements Message ---------------------------------------------- @@ -1029,7 +1075,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1062,6 +1108,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M inline const ::google::protobuf::EnumValueOptions& options() const; inline ::google::protobuf::EnumValueOptions* mutable_options(); + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -1114,6 +1161,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes static const ::google::protobuf::Descriptor* descriptor(); static const ServiceDescriptorProto& default_instance(); + void Swap(ServiceDescriptorProto* other); // implements Message ---------------------------------------------- @@ -1136,7 +1184,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1159,11 +1207,13 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes inline int method_size() const; inline void clear_method(); static const int kMethodFieldNumber = 2; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& method() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* mutable_method(); inline const ::google::protobuf::MethodDescriptorProto& method(int index) const; inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index); inline ::google::protobuf::MethodDescriptorProto* add_method(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& + method() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* + mutable_method(); // optional .google.protobuf.ServiceOptions options = 3; inline bool has_options() const; @@ -1172,6 +1222,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes inline const ::google::protobuf::ServiceOptions& options() const; inline ::google::protobuf::ServiceOptions* mutable_options(); + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -1224,6 +1275,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess static const ::google::protobuf::Descriptor* descriptor(); static const MethodDescriptorProto& default_instance(); + void Swap(MethodDescriptorProto* other); // implements Message ---------------------------------------------- @@ -1246,7 +1298,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1292,6 +1344,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess inline const ::google::protobuf::MethodOptions& options() const; inline ::google::protobuf::MethodOptions* mutable_options(); + // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -1347,6 +1400,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const FileOptions& default_instance(); + void Swap(FileOptions* other); // implements Message ---------------------------------------------- @@ -1369,7 +1423,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1387,6 +1441,8 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { FileOptions_OptimizeMode_OptimizeMode_MIN; static const OptimizeMode OptimizeMode_MAX = FileOptions_OptimizeMode_OptimizeMode_MAX; + static const int OptimizeMode_ARRAYSIZE = + FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE; static inline const ::google::protobuf::EnumDescriptor* OptimizeMode_descriptor() { return FileOptions_OptimizeMode_descriptor(); @@ -1435,17 +1491,41 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const; inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value); + // optional bool cc_generic_services = 16 [default = true]; + inline bool has_cc_generic_services() const; + inline void clear_cc_generic_services(); + static const int kCcGenericServicesFieldNumber = 16; + inline bool cc_generic_services() const; + inline void set_cc_generic_services(bool value); + + // optional bool java_generic_services = 17 [default = true]; + inline bool has_java_generic_services() const; + inline void clear_java_generic_services(); + static const int kJavaGenericServicesFieldNumber = 17; + inline bool java_generic_services() const; + inline void set_java_generic_services(bool value); + + // optional bool py_generic_services = 18 [default = true]; + inline bool has_py_generic_services() const; + inline void clear_py_generic_services(); + static const int kPyGenericServicesFieldNumber = 18; + inline bool py_generic_services() const; + inline void set_py_generic_services(bool value); + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* mutable_uninterpreted_option(); inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) private: ::google::protobuf::internal::ExtensionSet _extensions_; ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -1457,12 +1537,15 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { static const ::std::string _default_java_outer_classname_; bool java_multiple_files_; int optimize_for_; + bool cc_generic_services_; + bool java_generic_services_; + bool py_generic_services_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? inline bool _has_bit(int index) const { @@ -1502,6 +1585,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const MessageOptions& default_instance(); + void Swap(MessageOptions* other); // implements Message ---------------------------------------------- @@ -1524,7 +1608,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1551,13 +1635,16 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* mutable_uninterpreted_option(); inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) private: ::google::protobuf::internal::ExtensionSet _extensions_; ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -1610,6 +1697,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const FieldOptions& default_instance(); + void Swap(FieldOptions* other); // implements Message ---------------------------------------------- @@ -1632,7 +1720,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1640,6 +1728,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { // nested types ---------------------------------------------------- typedef FieldOptions_CType CType; + static const CType STRING = FieldOptions_CType_STRING; static const CType CORD = FieldOptions_CType_CORD; static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE; static inline bool CType_IsValid(int value) { @@ -1649,6 +1738,8 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { FieldOptions_CType_CType_MIN; static const CType CType_MAX = FieldOptions_CType_CType_MAX; + static const int CType_ARRAYSIZE = + FieldOptions_CType_CType_ARRAYSIZE; static inline const ::google::protobuf::EnumDescriptor* CType_descriptor() { return FieldOptions_CType_descriptor(); @@ -1663,7 +1754,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // optional .google.protobuf.FieldOptions.CType ctype = 1; + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; inline bool has_ctype() const; inline void clear_ctype(); static const int kCtypeFieldNumber = 1; @@ -1698,13 +1789,16 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* mutable_uninterpreted_option(); inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) private: ::google::protobuf::internal::ExtensionSet _extensions_; ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -1760,6 +1854,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const EnumOptions& default_instance(); + void Swap(EnumOptions* other); // implements Message ---------------------------------------------- @@ -1782,7 +1877,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1795,13 +1890,16 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* mutable_uninterpreted_option(); inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) private: ::google::protobuf::internal::ExtensionSet _extensions_; ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -1852,6 +1950,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const EnumValueOptions& default_instance(); + void Swap(EnumValueOptions* other); // implements Message ---------------------------------------------- @@ -1874,7 +1973,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1887,13 +1986,16 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* mutable_uninterpreted_option(); inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) private: ::google::protobuf::internal::ExtensionSet _extensions_; ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -1944,6 +2046,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const ServiceOptions& default_instance(); + void Swap(ServiceOptions* other); // implements Message ---------------------------------------------- @@ -1966,7 +2069,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -1979,13 +2082,16 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* mutable_uninterpreted_option(); inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) private: ::google::protobuf::internal::ExtensionSet _extensions_; ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -2036,6 +2142,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const MethodOptions& default_instance(); + void Swap(MethodOptions* other); // implements Message ---------------------------------------------- @@ -2058,7 +2165,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -2071,13 +2178,16 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { inline int uninterpreted_option_size() const; inline void clear_uninterpreted_option(); static const int kUninterpretedOptionFieldNumber = 999; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& uninterpreted_option() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* mutable_uninterpreted_option(); inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) private: ::google::protobuf::internal::ExtensionSet _extensions_; ::google::protobuf::UnknownFieldSet _unknown_fields_; @@ -2128,6 +2238,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu static const ::google::protobuf::Descriptor* descriptor(); static const UninterpretedOption_NamePart& default_instance(); + void Swap(UninterpretedOption_NamePart* other); // implements Message ---------------------------------------------- @@ -2150,7 +2261,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -2176,6 +2287,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu inline bool is_extension() const; inline void set_is_extension(bool value); + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -2227,6 +2339,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag static const ::google::protobuf::Descriptor* descriptor(); static const UninterpretedOption& default_instance(); + void Swap(UninterpretedOption* other); // implements Message ---------------------------------------------- @@ -2249,7 +2362,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const { _cached_size_ = size; } + void SetCachedSize(int size) const; public: ::google::protobuf::Metadata GetMetadata() const; @@ -2264,11 +2377,13 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag inline int name_size() const; inline void clear_name(); static const int kNameFieldNumber = 2; - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& name() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* mutable_name(); inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const; inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index); inline ::google::protobuf::UninterpretedOption_NamePart* add_name(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& + name() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* + mutable_name(); // optional string identifier_value = 3; inline bool has_identifier_value() const; @@ -2311,6 +2426,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag inline void set_string_value(const void* value, size_t size); inline ::std::string* mutable_string_value(); + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; @@ -2348,9 +2464,6 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag // =================================================================== - -// =================================================================== - // FileDescriptorSet // repeated .google.protobuf.FileDescriptorProto file = 1; @@ -2360,14 +2473,6 @@ inline int FileDescriptorSet::file_size() const { inline void FileDescriptorSet::clear_file() { file_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& -FileDescriptorSet::file() const { - return file_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* -FileDescriptorSet::mutable_file() { - return &file_; -} inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const { return file_.Get(index); } @@ -2377,6 +2482,14 @@ inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file( inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() { return file_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +FileDescriptorSet::file() const { + return file_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +FileDescriptorSet::mutable_file() { + return &file_; +} // ------------------------------------------------------------------- @@ -2473,14 +2586,6 @@ inline int FileDescriptorProto::dependency_size() const { inline void FileDescriptorProto::clear_dependency() { dependency_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::std::string>& -FileDescriptorProto::dependency() const { - return dependency_; -} -inline ::google::protobuf::RepeatedPtrField< ::std::string>* -FileDescriptorProto::mutable_dependency() { - return &dependency_; -} inline const ::std::string& FileDescriptorProto::dependency(int index) const { return dependency_.Get(index); } @@ -2509,6 +2614,14 @@ inline void FileDescriptorProto::add_dependency(const char* value) { inline void FileDescriptorProto::add_dependency(const char* value, size_t size) { dependency_.Add()->assign(reinterpret_cast<const char*>(value), size); } +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +FileDescriptorProto::dependency() const { + return dependency_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +FileDescriptorProto::mutable_dependency() { + return &dependency_; +} // repeated .google.protobuf.DescriptorProto message_type = 4; inline int FileDescriptorProto::message_type_size() const { @@ -2517,14 +2630,6 @@ inline int FileDescriptorProto::message_type_size() const { inline void FileDescriptorProto::clear_message_type() { message_type_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& -FileDescriptorProto::message_type() const { - return message_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* -FileDescriptorProto::mutable_message_type() { - return &message_type_; -} inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const { return message_type_.Get(index); } @@ -2534,6 +2639,14 @@ inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() { return message_type_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& +FileDescriptorProto::message_type() const { + return message_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* +FileDescriptorProto::mutable_message_type() { + return &message_type_; +} // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; inline int FileDescriptorProto::enum_type_size() const { @@ -2542,14 +2655,6 @@ inline int FileDescriptorProto::enum_type_size() const { inline void FileDescriptorProto::clear_enum_type() { enum_type_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& -FileDescriptorProto::enum_type() const { - return enum_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* -FileDescriptorProto::mutable_enum_type() { - return &enum_type_; -} inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const { return enum_type_.Get(index); } @@ -2559,6 +2664,14 @@ inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enu inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() { return enum_type_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& +FileDescriptorProto::enum_type() const { + return enum_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* +FileDescriptorProto::mutable_enum_type() { + return &enum_type_; +} // repeated .google.protobuf.ServiceDescriptorProto service = 6; inline int FileDescriptorProto::service_size() const { @@ -2567,14 +2680,6 @@ inline int FileDescriptorProto::service_size() const { inline void FileDescriptorProto::clear_service() { service_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& -FileDescriptorProto::service() const { - return service_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* -FileDescriptorProto::mutable_service() { - return &service_; -} inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const { return service_.Get(index); } @@ -2584,6 +2689,14 @@ inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_ inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() { return service_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& +FileDescriptorProto::service() const { + return service_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* +FileDescriptorProto::mutable_service() { + return &service_; +} // repeated .google.protobuf.FieldDescriptorProto extension = 7; inline int FileDescriptorProto::extension_size() const { @@ -2592,14 +2705,6 @@ inline int FileDescriptorProto::extension_size() const { inline void FileDescriptorProto::clear_extension() { extension_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -FileDescriptorProto::extension() const { - return extension_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -FileDescriptorProto::mutable_extension() { - return &extension_; -} inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const { return extension_.Get(index); } @@ -2609,6 +2714,14 @@ inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_ex inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() { return extension_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +FileDescriptorProto::extension() const { + return extension_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +FileDescriptorProto::mutable_extension() { + return &extension_; +} // optional .google.protobuf.FileOptions options = 8; inline bool FileDescriptorProto::has_options() const { @@ -2716,14 +2829,6 @@ inline int DescriptorProto::field_size() const { inline void DescriptorProto::clear_field() { field_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -DescriptorProto::field() const { - return field_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -DescriptorProto::mutable_field() { - return &field_; -} inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const { return field_.Get(index); } @@ -2733,6 +2838,14 @@ inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field( inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() { return field_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +DescriptorProto::field() const { + return field_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +DescriptorProto::mutable_field() { + return &field_; +} // repeated .google.protobuf.FieldDescriptorProto extension = 6; inline int DescriptorProto::extension_size() const { @@ -2741,14 +2854,6 @@ inline int DescriptorProto::extension_size() const { inline void DescriptorProto::clear_extension() { extension_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -DescriptorProto::extension() const { - return extension_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -DescriptorProto::mutable_extension() { - return &extension_; -} inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const { return extension_.Get(index); } @@ -2758,6 +2863,14 @@ inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extens inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() { return extension_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +DescriptorProto::extension() const { + return extension_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +DescriptorProto::mutable_extension() { + return &extension_; +} // repeated .google.protobuf.DescriptorProto nested_type = 3; inline int DescriptorProto::nested_type_size() const { @@ -2766,14 +2879,6 @@ inline int DescriptorProto::nested_type_size() const { inline void DescriptorProto::clear_nested_type() { nested_type_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& -DescriptorProto::nested_type() const { - return nested_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* -DescriptorProto::mutable_nested_type() { - return &nested_type_; -} inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const { return nested_type_.Get(index); } @@ -2783,6 +2888,14 @@ inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() { return nested_type_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& +DescriptorProto::nested_type() const { + return nested_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* +DescriptorProto::mutable_nested_type() { + return &nested_type_; +} // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; inline int DescriptorProto::enum_type_size() const { @@ -2791,14 +2904,6 @@ inline int DescriptorProto::enum_type_size() const { inline void DescriptorProto::clear_enum_type() { enum_type_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& -DescriptorProto::enum_type() const { - return enum_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* -DescriptorProto::mutable_enum_type() { - return &enum_type_; -} inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const { return enum_type_.Get(index); } @@ -2808,6 +2913,14 @@ inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_ty inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() { return enum_type_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& +DescriptorProto::enum_type() const { + return enum_type_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* +DescriptorProto::mutable_enum_type() { + return &enum_type_; +} // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; inline int DescriptorProto::extension_range_size() const { @@ -2816,14 +2929,6 @@ inline int DescriptorProto::extension_range_size() const { inline void DescriptorProto::clear_extension_range() { extension_range_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& -DescriptorProto::extension_range() const { - return extension_range_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* -DescriptorProto::mutable_extension_range() { - return &extension_range_; -} inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const { return extension_range_.Get(index); } @@ -2833,6 +2938,14 @@ inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::muta inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() { return extension_range_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& +DescriptorProto::extension_range() const { + return extension_range_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* +DescriptorProto::mutable_extension_range() { + return &extension_range_; +} // optional .google.protobuf.MessageOptions options = 7; inline bool DescriptorProto::has_options() const { @@ -3143,14 +3256,6 @@ inline int EnumDescriptorProto::value_size() const { inline void EnumDescriptorProto::clear_value() { value_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& -EnumDescriptorProto::value() const { - return value_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* -EnumDescriptorProto::mutable_value() { - return &value_; -} inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const { return value_.Get(index); } @@ -3160,6 +3265,14 @@ inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutabl inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() { return value_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& +EnumDescriptorProto::value() const { + return value_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* +EnumDescriptorProto::mutable_value() { + return &value_; +} // optional .google.protobuf.EnumOptions options = 3; inline bool EnumDescriptorProto::has_options() const { @@ -3310,14 +3423,6 @@ inline int ServiceDescriptorProto::method_size() const { inline void ServiceDescriptorProto::clear_method() { method_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& -ServiceDescriptorProto::method() const { - return method_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* -ServiceDescriptorProto::mutable_method() { - return &method_; -} inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const { return method_.Get(index); } @@ -3327,6 +3432,14 @@ inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutabl inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() { return method_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& +ServiceDescriptorProto::method() const { + return method_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* +ServiceDescriptorProto::mutable_method() { + return &method_; +} // optional .google.protobuf.ServiceOptions options = 3; inline bool ServiceDescriptorProto::has_options() const { @@ -3613,6 +3726,54 @@ inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_Optimi optimize_for_ = value; } +// optional bool cc_generic_services = 16 [default = true]; +inline bool FileOptions::has_cc_generic_services() const { + return _has_bit(4); +} +inline void FileOptions::clear_cc_generic_services() { + cc_generic_services_ = true; + _clear_bit(4); +} +inline bool FileOptions::cc_generic_services() const { + return cc_generic_services_; +} +inline void FileOptions::set_cc_generic_services(bool value) { + _set_bit(4); + cc_generic_services_ = value; +} + +// optional bool java_generic_services = 17 [default = true]; +inline bool FileOptions::has_java_generic_services() const { + return _has_bit(5); +} +inline void FileOptions::clear_java_generic_services() { + java_generic_services_ = true; + _clear_bit(5); +} +inline bool FileOptions::java_generic_services() const { + return java_generic_services_; +} +inline void FileOptions::set_java_generic_services(bool value) { + _set_bit(5); + java_generic_services_ = value; +} + +// optional bool py_generic_services = 18 [default = true]; +inline bool FileOptions::has_py_generic_services() const { + return _has_bit(6); +} +inline void FileOptions::clear_py_generic_services() { + py_generic_services_ = true; + _clear_bit(6); +} +inline bool FileOptions::py_generic_services() const { + return py_generic_services_; +} +inline void FileOptions::set_py_generic_services(bool value) { + _set_bit(6); + py_generic_services_ = value; +} + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int FileOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); @@ -3620,14 +3781,6 @@ inline int FileOptions::uninterpreted_option_size() const { inline void FileOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -FileOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -FileOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const { return uninterpreted_option_.Get(index); } @@ -3637,6 +3790,14 @@ inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpret inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() { return uninterpreted_option_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +FileOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +FileOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} // ------------------------------------------------------------------- @@ -3681,14 +3842,6 @@ inline int MessageOptions::uninterpreted_option_size() const { inline void MessageOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -MessageOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -MessageOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const { return uninterpreted_option_.Get(index); } @@ -3698,17 +3851,25 @@ inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterp inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() { return uninterpreted_option_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +MessageOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +MessageOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} // ------------------------------------------------------------------- // FieldOptions -// optional .google.protobuf.FieldOptions.CType ctype = 1; +// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; inline bool FieldOptions::has_ctype() const { return _has_bit(0); } inline void FieldOptions::clear_ctype() { - ctype_ = 1; + ctype_ = 0; _clear_bit(0); } inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const { @@ -3801,14 +3962,6 @@ inline int FieldOptions::uninterpreted_option_size() const { inline void FieldOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -FieldOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -FieldOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const { return uninterpreted_option_.Get(index); } @@ -3818,6 +3971,14 @@ inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpre inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() { return uninterpreted_option_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +FieldOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +FieldOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} // ------------------------------------------------------------------- @@ -3830,14 +3991,6 @@ inline int EnumOptions::uninterpreted_option_size() const { inline void EnumOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -EnumOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -EnumOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const { return uninterpreted_option_.Get(index); } @@ -3847,6 +4000,14 @@ inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpret inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() { return uninterpreted_option_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +EnumOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +EnumOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} // ------------------------------------------------------------------- @@ -3859,14 +4020,6 @@ inline int EnumValueOptions::uninterpreted_option_size() const { inline void EnumValueOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -EnumValueOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -EnumValueOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const { return uninterpreted_option_.Get(index); } @@ -3876,6 +4029,14 @@ inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninte inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() { return uninterpreted_option_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +EnumValueOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +EnumValueOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} // ------------------------------------------------------------------- @@ -3888,14 +4049,6 @@ inline int ServiceOptions::uninterpreted_option_size() const { inline void ServiceOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -ServiceOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -ServiceOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const { return uninterpreted_option_.Get(index); } @@ -3905,6 +4058,14 @@ inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterp inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() { return uninterpreted_option_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +ServiceOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +ServiceOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} // ------------------------------------------------------------------- @@ -3917,14 +4078,6 @@ inline int MethodOptions::uninterpreted_option_size() const { inline void MethodOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& -MethodOptions::uninterpreted_option() const { - return uninterpreted_option_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* -MethodOptions::mutable_uninterpreted_option() { - return &uninterpreted_option_; -} inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const { return uninterpreted_option_.Get(index); } @@ -3934,6 +4087,14 @@ inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpr inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() { return uninterpreted_option_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +MethodOptions::uninterpreted_option() const { + return uninterpreted_option_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +MethodOptions::mutable_uninterpreted_option() { + return &uninterpreted_option_; +} // ------------------------------------------------------------------- @@ -4008,14 +4169,6 @@ inline int UninterpretedOption::name_size() const { inline void UninterpretedOption::clear_name() { name_.Clear(); } -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& -UninterpretedOption::name() const { - return name_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* -UninterpretedOption::mutable_name() { - return &name_; -} inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const { return name_.Get(index); } @@ -4025,6 +4178,14 @@ inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mu inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() { return name_.Add(); } +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& +UninterpretedOption::name() const { + return name_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* +UninterpretedOption::mutable_name() { + return &name_; +} // optional string identifier_value = 3; inline bool UninterpretedOption::has_identifier_value() const { @@ -4159,6 +4320,8 @@ inline ::std::string* UninterpretedOption::mutable_string_value() { } +// @@protoc_insertion_point(namespace_scope) + } // namespace protobuf } // namespace google @@ -4187,4 +4350,6 @@ inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions } // namespace protobuf #endif // SWIG +// @@protoc_insertion_point(global_scope) + #endif // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 4db88a8..cc04aa8 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -256,6 +256,22 @@ message FileOptions { + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of proto2. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. If you are + // using such a plugin, set these to false. In the future, we may change + // the default to false, so if you explicitly want generic services, you + // should explicitly set these to true. + optional bool cc_generic_services = 16 [default=true]; + optional bool java_generic_services = 17 [default=true]; + optional bool py_generic_services = 18 [default=true]; + // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; @@ -301,8 +317,11 @@ message FieldOptions { // representation of the field than it normally would. See the specific // options below. This option is not yet implemented in the open source // release -- sorry, we'll try to include it in a future version! - optional CType ctype = 1; + optional CType ctype = 1 [default = STRING]; enum CType { + // Default mode. + STRING = 0; + CORD = 1; STRING_PIECE = 2; @@ -313,6 +332,7 @@ message FieldOptions { // a single length-delimited blob. optional bool packed = 2; + // Is this field deprecated? // Depending on the target platform, this can emit Deprecated annotations // for accessors, or it will be completely ignored; in the very least, this diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index 6ea674d..95708d9 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -37,6 +37,7 @@ #include <set> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/wire_format_lite_inl.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/stl_util-inl.h> #include <google/protobuf/stubs/map-util.h> @@ -336,6 +337,35 @@ bool EncodedDescriptorDatabase::FindFileContainingSymbol( return MaybeParse(index_.FindSymbol(symbol_name), output); } +bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( + const string& symbol_name, + string* output) { + pair<const void*, int> encoded_file = index_.FindSymbol(symbol_name); + if (encoded_file.first == NULL) return false; + + // Optimization: The name should be the first field in the encoded message. + // Try to just read it directly. + io::CodedInputStream input(reinterpret_cast<const uint8*>(encoded_file.first), + encoded_file.second); + + const uint32 kNameTag = internal::WireFormatLite::MakeTag( + FileDescriptorProto::kNameFieldNumber, + internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + if (input.ReadTag() == kNameTag) { + // Success! + return internal::WireFormatLite::ReadString(&input, output); + } else { + // Slow path. Parse whole message. + FileDescriptorProto file_proto; + if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) { + return false; + } + *output = file_proto.name(); + return true; + } +} + bool EncodedDescriptorDatabase::FindFileContainingExtension( const string& containing_type, int field_number, diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h index c23ab75..f32b1db 100644 --- a/src/google/protobuf/descriptor_database.h +++ b/src/google/protobuf/descriptor_database.h @@ -280,6 +280,10 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { // need to keep it around. bool AddCopy(const void* encoded_file_descriptor, int size); + // Like FindFileContainingSymbol but returns only the name of the file. + bool FindNameOfFileContainingSymbol(const string& symbol_name, + string* output); + // implements DescriptorDatabase ----------------------------------- bool FindFileByName(const string& filename, FileDescriptorProto* output); diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc index 33de134..ac72ddc 100644 --- a/src/google/protobuf/descriptor_database_unittest.cc +++ b/src/google/protobuf/descriptor_database_unittest.cc @@ -480,6 +480,40 @@ INSTANTIATE_TEST_CASE_P(Pool, DescriptorDatabaseTest, #endif // GTEST_HAS_PARAM_TEST +TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) { + // Create two files, one of which is in two parts. + FileDescriptorProto file1, file2a, file2b; + file1.set_name("foo.proto"); + file1.set_package("foo"); + file1.add_message_type()->set_name("Foo"); + file2a.set_name("bar.proto"); + file2b.set_package("bar"); + file2b.add_message_type()->set_name("Bar"); + + // Normal serialization allows our optimization to kick in. + string data1 = file1.SerializeAsString(); + + // Force out-of-order serialization to test slow path. + string data2 = file2b.SerializeAsString() + file2a.SerializeAsString(); + + // Create EncodedDescriptorDatabase containing both files. + EncodedDescriptorDatabase db; + db.Add(data1.data(), data1.size()); + db.Add(data2.data(), data2.size()); + + // Test! + string filename; + EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo", &filename)); + EXPECT_EQ("foo.proto", filename); + EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo.Blah", &filename)); + EXPECT_EQ("foo.proto", filename); + EXPECT_TRUE(db.FindNameOfFileContainingSymbol("bar.Bar", &filename)); + EXPECT_EQ("bar.proto", filename); + EXPECT_FALSE(db.FindNameOfFileContainingSymbol("foo", &filename)); + EXPECT_FALSE(db.FindNameOfFileContainingSymbol("bar", &filename)); + EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename)); +} + // =================================================================== class MergedDescriptorDatabaseTest : public testing::Test { diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 8fcfba3..ec2c815 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -3948,6 +3948,9 @@ TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) { EXPECT_EQ(0, call_counter.call_count_); } +// =================================================================== + + } // namespace descriptor_unittest } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index f8b5b4e..c711a2d 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -106,7 +106,11 @@ int FieldSpaceUsed(const FieldDescriptor* field) { case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField<Message>); case FD::CPPTYPE_STRING: - return sizeof(RepeatedPtrField<string>); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return sizeof(RepeatedPtrField<string>); + } break; } } else { @@ -122,7 +126,11 @@ int FieldSpaceUsed(const FieldDescriptor* field) { case FD::CPPTYPE_MESSAGE: return sizeof(Message*); case FD::CPPTYPE_STRING: - return sizeof(string*); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return sizeof(string*); + } break; } } @@ -262,19 +270,24 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info) break; case FieldDescriptor::CPPTYPE_STRING: - if (!field->is_repeated()) { - if (is_prototype()) { - new(field_ptr) const string*(&field->default_value_string()); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + if (!field->is_repeated()) { + if (is_prototype()) { + new(field_ptr) const string*(&field->default_value_string()); + } else { + string* default_value = + *reinterpret_cast<string* const*>( + type_info_->prototype->OffsetToPointer( + type_info_->offsets[i])); + new(field_ptr) string*(default_value); + } } else { - string* default_value = - *reinterpret_cast<string* const*>( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])); - new(field_ptr) string*(default_value); + new(field_ptr) RepeatedPtrField<string>(); } - } else { - new(field_ptr) RepeatedPtrField<string>(); - } + break; + } break; case FieldDescriptor::CPPTYPE_MESSAGE: { @@ -329,8 +342,13 @@ DynamicMessage::~DynamicMessage() { #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_STRING: - reinterpret_cast<RepeatedPtrField<string>*>(field_ptr) - ->~RepeatedPtrField<string>(); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + reinterpret_cast<RepeatedPtrField<string>*>(field_ptr) + ->~RepeatedPtrField<string>(); + break; + } break; case FieldDescriptor::CPPTYPE_MESSAGE: @@ -340,10 +358,16 @@ DynamicMessage::~DynamicMessage() { } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - string* ptr = *reinterpret_cast<string**>(field_ptr); - if (ptr != &field->default_value_string()) { - delete ptr; + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + string* ptr = *reinterpret_cast<string**>(field_ptr); + if (ptr != &field->default_value_string()) { + delete ptr; + } + break; } + } } else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) && !is_prototype()) { Message* message = *reinterpret_cast<Message**>(field_ptr); @@ -373,7 +397,7 @@ void DynamicMessage::CrossLinkPrototypes() { // For singular fields, the field is just a pointer which should // point to the prototype. *reinterpret_cast<const Message**>(field_ptr) = - factory->GetPrototype(field->message_type()); + factory->GetPrototypeNoLock(field->message_type()); } } } @@ -410,11 +434,13 @@ struct DynamicMessageFactory::PrototypeMap { }; DynamicMessageFactory::DynamicMessageFactory() - : pool_(NULL), prototypes_(new PrototypeMap) { + : pool_(NULL), delegate_to_generated_factory_(false), + prototypes_(new PrototypeMap) { } DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool) - : pool_(pool), prototypes_(new PrototypeMap) { + : pool_(pool), delegate_to_generated_factory_(false), + prototypes_(new PrototypeMap) { } DynamicMessageFactory::~DynamicMessageFactory() { @@ -424,8 +450,18 @@ DynamicMessageFactory::~DynamicMessageFactory() { } } - const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) { + MutexLock lock(&prototypes_mutex_); + return GetPrototypeNoLock(type); +} + +const Message* DynamicMessageFactory::GetPrototypeNoLock( + const Descriptor* type) { + if (delegate_to_generated_factory_ && + type->file()->pool() == DescriptorPool::generated_pool()) { + return MessageFactory::generated_factory()->GetPrototype(type); + } + const DynamicMessage::TypeInfo** target = &prototypes_->map_[type]; if (*target != NULL) { // Already exists. diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h index f38d3b0..81dd2c6 100644 --- a/src/google/protobuf/dynamic_message.h +++ b/src/google/protobuf/dynamic_message.h @@ -73,9 +73,25 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { // Construct a DynamicMessageFactory that will search for extensions in // the given DescriptorPool. + // + // DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the + // parser to look for extensions in an alternate pool. However, note that + // this is almost never what you want to do. Almost all users should use + // the zero-arg constructor. DynamicMessageFactory(const DescriptorPool* pool); + ~DynamicMessageFactory(); + // Call this to tell the DynamicMessageFactory that if it is given a + // Descriptor d for which: + // d->file()->pool() == DescriptorPool::generated_pool(), + // then it should delegate to MessageFactory::generated_factory() instead + // of constructing a dynamic implementation of the message. In theory there + // is no down side to doing this, so it may become the default in the future. + void SetDelegateToGeneratedFactory(bool enable) { + delegate_to_generated_factory_ = enable; + } + // implements MessageFactory --------------------------------------- // Given a Descriptor, constructs the default (prototype) Message of that @@ -92,14 +108,12 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { // The given descriptor must outlive the returned message, and hence must // outlive the DynamicMessageFactory. // - // Note that while GetPrototype() is idempotent, it is not const. This - // implies that it is not thread-safe to call GetPrototype() on the same - // DynamicMessageFactory in two different threads simultaneously. However, - // the returned objects are just as thread-safe as any other Message. + // The method is thread-safe. const Message* GetPrototype(const Descriptor* type); private: const DescriptorPool* pool_; + bool delegate_to_generated_factory_; // This struct just contains a hash_map. We can't #include <google/protobuf/stubs/hash.h> from // this header due to hacks needed for hash_map portability in the open source @@ -108,6 +122,10 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { // headers may only #include other public headers. struct PrototypeMap; scoped_ptr<PrototypeMap> prototypes_; + mutable Mutex prototypes_mutex_; + + friend class DynamicMessage; + const Message* GetPrototypeNoLock(const Descriptor* type); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory); }; @@ -116,4 +134,3 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { } // namespace google #endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ - diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 4d5eb6c..6084885 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -59,20 +59,6 @@ inline WireFormatLite::CppType cpp_type(FieldType type) { } // Registry stuff. -struct ExtensionInfo { - inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed) - : type(type), is_repeated(is_repeated), is_packed(is_packed) {} - - FieldType type; - bool is_repeated; - bool is_packed; - - union { - ExtensionSet::EnumValidityFunc* enum_is_valid; - const MessageLite* message_prototype; - }; -}; - typedef hash_map<pair<const MessageLite*, int>, ExtensionInfo> ExtensionRegistry; ExtensionRegistry* registry_ = NULL; @@ -110,6 +96,19 @@ const ExtensionInfo* FindRegisteredExtension( } // namespace +ExtensionFinder::~ExtensionFinder() {} + +bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { + const ExtensionInfo* extension = + FindRegisteredExtension(containing_type_, number); + if (extension == NULL) { + return false; + } else { + *output = *extension; + return true; + } +} + void ExtensionSet::RegisterExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed) { @@ -120,13 +119,28 @@ void ExtensionSet::RegisterExtension(const MessageLite* containing_type, Register(containing_type, number, info); } +static bool CallNoArgValidityFunc(const void* arg, int number) { + // Note: Must use C-style cast here rather than reinterpret_cast because + // the C++ standard at one point did not allow casts between function and + // data pointers and some compilers enforce this for C++-style casts. No + // compiler enforces it for C-style casts since lots of C-style code has + // relied on these kinds of casts for a long time, despite being + // technically undefined. See: + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195 + // Also note: Some compilers do not allow function pointers to be "const". + // Which makes sense, I suppose, because it's meaningless. + return ((EnumValidityFunc*)arg)(number); +} + void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid) { GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); ExtensionInfo info(type, is_repeated, is_packed); - info.enum_is_valid = is_valid; + info.enum_validity_check.func = CallNoArgValidityFunc; + // See comment in CallNoArgValidityFunc() about why we use a c-style cast. + info.enum_validity_check.arg = (void*)is_valid; Register(containing_type, number, info); } @@ -211,9 +225,10 @@ LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \ } \ \ void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ - LOWERCASE value) { \ + LOWERCASE value, \ + const FieldDescriptor* descriptor) { \ Extension* extension; \ - if (MaybeNewExtension(number, &extension)) { \ + if (MaybeNewExtension(number, descriptor, &extension)) { \ extension->type = type; \ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ extension->is_repeated = false; \ @@ -240,9 +255,10 @@ void ExtensionSet::SetRepeated##CAMELCASE( \ } \ \ void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ - bool packed, LOWERCASE value) { \ + bool packed, LOWERCASE value, \ + const FieldDescriptor* descriptor) { \ Extension* extension; \ - if (MaybeNewExtension(number, &extension)) { \ + if (MaybeNewExtension(number, descriptor, &extension)) { \ extension->type = type; \ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ extension->is_repeated = true; \ @@ -279,9 +295,10 @@ int ExtensionSet::GetEnum(int number, int default_value) const { } } -void ExtensionSet::SetEnum(int number, FieldType type, int value) { +void ExtensionSet::SetEnum(int number, FieldType type, int value, + const FieldDescriptor* descriptor) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { + if (MaybeNewExtension(number, descriptor, &extension)) { extension->type = type; GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); extension->is_repeated = false; @@ -307,9 +324,10 @@ void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { } void ExtensionSet::AddEnum(int number, FieldType type, - bool packed, int value) { + bool packed, int value, + const FieldDescriptor* descriptor) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { + if (MaybeNewExtension(number, descriptor, &extension)) { extension->type = type; GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); extension->is_repeated = true; @@ -337,9 +355,10 @@ const string& ExtensionSet::GetString(int number, } } -string* ExtensionSet::MutableString(int number, FieldType type) { +string* ExtensionSet::MutableString(int number, FieldType type, + const FieldDescriptor* descriptor) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { + if (MaybeNewExtension(number, descriptor, &extension)) { extension->type = type; GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); extension->is_repeated = false; @@ -365,9 +384,10 @@ string* ExtensionSet::MutableRepeatedString(int number, int index) { return iter->second.repeated_string_value->Mutable(index); } -string* ExtensionSet::AddString(int number, FieldType type) { +string* ExtensionSet::AddString(int number, FieldType type, + const FieldDescriptor* descriptor) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { + if (MaybeNewExtension(number, descriptor, &extension)) { extension->type = type; GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); extension->is_repeated = true; @@ -400,9 +420,10 @@ const MessageLite& ExtensionSet::GetMessage( // MessageFactory* factory) const MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, - const MessageLite& prototype) { + const MessageLite& prototype, + const FieldDescriptor* descriptor) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { + if (MaybeNewExtension(number, descriptor, &extension)) { extension->type = type; GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = false; @@ -435,9 +456,10 @@ MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { } MessageLite* ExtensionSet::AddMessage(int number, FieldType type, - const MessageLite& prototype) { + const MessageLite& prototype, + const FieldDescriptor* descriptor) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { + if (MaybeNewExtension(number, descriptor, &extension)) { extension->type = type; GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = true; @@ -563,7 +585,8 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { if (other_extension.is_repeated) { Extension* extension; - bool is_new = MaybeNewExtension(iter->first, &extension); + bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor, + &extension); if (is_new) { // Extension did not already exist in set. extension->type = other_extension.type; @@ -622,7 +645,8 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ case WireFormatLite::CPPTYPE_##UPPERCASE: \ Set##CAMELCASE(iter->first, other_extension.type, \ - other_extension.LOWERCASE##_value); \ + other_extension.LOWERCASE##_value, \ + other_extension.descriptor); \ break; HANDLE_TYPE( INT32, int32, Int32); @@ -636,11 +660,13 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { #undef HANDLE_TYPE case WireFormatLite::CPPTYPE_STRING: SetString(iter->first, other_extension.type, - *other_extension.string_value); + *other_extension.string_value, + other_extension.descriptor); break; case WireFormatLite::CPPTYPE_MESSAGE: MutableMessage(iter->first, other_extension.type, - *other_extension.message_value) + *other_extension.message_value, + other_extension.descriptor) ->CheckTypeAndMergeFrom(*other_extension.message_value); break; } @@ -678,64 +704,67 @@ bool ExtensionSet::IsInitialized() const { } bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type, + ExtensionFinder* extension_finder, FieldSkipper* field_skipper) { int number = WireFormatLite::GetTagFieldNumber(tag); WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); - const ExtensionInfo* extension = - FindRegisteredExtension(containing_type, number); - + ExtensionInfo extension; bool is_unknown; - if (extension == NULL) { + if (!extension_finder->Find(number, &extension)) { is_unknown = true; - } else if (extension->is_packed) { + } else if (extension.is_packed) { is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); } else { WireFormatLite::WireType expected_wire_type = - WireFormatLite::WireTypeForFieldType(real_type(extension->type)); + WireFormatLite::WireTypeForFieldType(real_type(extension.type)); is_unknown = (wire_type != expected_wire_type); } if (is_unknown) { field_skipper->SkipField(input, tag); - } else if (extension->is_packed) { + } else if (extension.is_packed) { uint32 size; if (!input->ReadVarint32(&size)) return false; io::CodedInputStream::Limit limit = input->PushLimit(size); - switch (extension->type) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ + switch (extension.type) { +#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ case WireFormatLite::TYPE_##UPPERCASE: \ while (input->BytesUntilLimit() > 0) { \ CPP_LOWERCASE value; \ - if (!WireFormatLite::Read##CAMELCASE(input, &value)) return false; \ + if (!WireFormatLite::ReadPrimitive< \ + CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ + input, &value)) return false; \ Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ - true, value); \ + true, value, extension.descriptor); \ } \ break - HANDLE_TYPE( INT32, Int32, Int32, int32); - HANDLE_TYPE( INT64, Int64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, Int32, int32); - HANDLE_TYPE( SINT64, SInt64, Int64, int64); - HANDLE_TYPE( FIXED32, Fixed32, UInt32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, UInt64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, Int32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, Int64, int64); - HANDLE_TYPE( FLOAT, Float, Float, float); - HANDLE_TYPE( DOUBLE, Double, Double, double); - HANDLE_TYPE( BOOL, Bool, Bool, bool); + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, Int32, int32); + HANDLE_TYPE( SINT64, Int64, int64); + HANDLE_TYPE( FIXED32, UInt32, uint32); + HANDLE_TYPE( FIXED64, UInt64, uint64); + HANDLE_TYPE(SFIXED32, Int32, int32); + HANDLE_TYPE(SFIXED64, Int64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); #undef HANDLE_TYPE case WireFormatLite::TYPE_ENUM: while (input->BytesUntilLimit() > 0) { int value; - if (!WireFormatLite::ReadEnum(input, &value)) return false; - if (extension->enum_is_valid(value)) { - AddEnum(number, WireFormatLite::TYPE_ENUM, true, value); + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) return false; + if (extension.enum_validity_check.func( + extension.enum_validity_check.arg, value)) { + AddEnum(number, WireFormatLite::TYPE_ENUM, true, value, + extension.descriptor); } } break; @@ -750,81 +779,90 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, input->PopLimit(limit); } else { - switch (extension->type) { -#define HANDLE_TYPE(UPPERCASE, CAMELCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ + switch (extension.type) { +#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ case WireFormatLite::TYPE_##UPPERCASE: { \ CPP_LOWERCASE value; \ - if (!WireFormatLite::Read##CAMELCASE(input, &value)) return false; \ - if (extension->is_repeated) { \ + if (!WireFormatLite::ReadPrimitive< \ + CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ + input, &value)) return false; \ + if (extension.is_repeated) { \ Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ - false, value); \ + false, value, extension.descriptor); \ } else { \ - Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value); \ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ + extension.descriptor); \ } \ } break - HANDLE_TYPE( INT32, Int32, Int32, int32); - HANDLE_TYPE( INT64, Int64, Int64, int64); - HANDLE_TYPE( UINT32, UInt32, UInt32, uint32); - HANDLE_TYPE( UINT64, UInt64, UInt64, uint64); - HANDLE_TYPE( SINT32, SInt32, Int32, int32); - HANDLE_TYPE( SINT64, SInt64, Int64, int64); - HANDLE_TYPE( FIXED32, Fixed32, UInt32, uint32); - HANDLE_TYPE( FIXED64, Fixed64, UInt64, uint64); - HANDLE_TYPE(SFIXED32, SFixed32, Int32, int32); - HANDLE_TYPE(SFIXED64, SFixed64, Int64, int64); - HANDLE_TYPE( FLOAT, Float, Float, float); - HANDLE_TYPE( DOUBLE, Double, Double, double); - HANDLE_TYPE( BOOL, Bool, Bool, bool); + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, Int32, int32); + HANDLE_TYPE( SINT64, Int64, int64); + HANDLE_TYPE( FIXED32, UInt32, uint32); + HANDLE_TYPE( FIXED64, UInt64, uint64); + HANDLE_TYPE(SFIXED32, Int32, int32); + HANDLE_TYPE(SFIXED64, Int64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); #undef HANDLE_TYPE case WireFormatLite::TYPE_ENUM: { int value; - if (!WireFormatLite::ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) return false; - if (!extension->enum_is_valid(value)) { + if (!extension.enum_validity_check.func( + extension.enum_validity_check.arg, value)) { // Invalid value. Treat as unknown. field_skipper->SkipUnknownEnum(number, value); - } else if (extension->is_repeated) { - AddEnum(number, WireFormatLite::TYPE_ENUM, false, value); + } else if (extension.is_repeated) { + AddEnum(number, WireFormatLite::TYPE_ENUM, false, value, + extension.descriptor); } else { - SetEnum(number, WireFormatLite::TYPE_ENUM, value); + SetEnum(number, WireFormatLite::TYPE_ENUM, value, + extension.descriptor); } break; } case WireFormatLite::TYPE_STRING: { - string* value = extension->is_repeated ? - AddString(number, WireFormatLite::TYPE_STRING) : - MutableString(number, WireFormatLite::TYPE_STRING); + string* value = extension.is_repeated ? + AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : + MutableString(number, WireFormatLite::TYPE_STRING, + extension.descriptor); if (!WireFormatLite::ReadString(input, value)) return false; break; } case WireFormatLite::TYPE_BYTES: { - string* value = extension->is_repeated ? - AddString(number, WireFormatLite::TYPE_STRING) : - MutableString(number, WireFormatLite::TYPE_STRING); + string* value = extension.is_repeated ? + AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : + MutableString(number, WireFormatLite::TYPE_STRING, + extension.descriptor); if (!WireFormatLite::ReadBytes(input, value)) return false; break; } case WireFormatLite::TYPE_GROUP: { - MessageLite* value = extension->is_repeated ? + MessageLite* value = extension.is_repeated ? AddMessage(number, WireFormatLite::TYPE_GROUP, - *extension->message_prototype) : + *extension.message_prototype, extension.descriptor) : MutableMessage(number, WireFormatLite::TYPE_GROUP, - *extension->message_prototype); + *extension.message_prototype, extension.descriptor); if (!WireFormatLite::ReadGroup(number, input, value)) return false; break; } case WireFormatLite::TYPE_MESSAGE: { - MessageLite* value = extension->is_repeated ? + MessageLite* value = extension.is_repeated ? AddMessage(number, WireFormatLite::TYPE_MESSAGE, - *extension->message_prototype) : + *extension.message_prototype, extension.descriptor) : MutableMessage(number, WireFormatLite::TYPE_MESSAGE, - *extension->message_prototype); + *extension.message_prototype, extension.descriptor); if (!WireFormatLite::ReadMessage(input, value)) return false; break; } @@ -837,7 +875,8 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, const MessageLite* containing_type) { FieldSkipper skipper; - return ParseField(tag, input, containing_type, &skipper); + GeneratedExtensionFinder finder(containing_type); + return ParseField(tag, input, &finder, &skipper); } // Defined in extension_set_heavy.cc. @@ -846,7 +885,7 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, // UnknownFieldSet* unknown_fields) bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type, + ExtensionFinder* extension_finder, FieldSkipper* field_skipper) { while (true) { uint32 tag = input->ReadTag(); @@ -854,12 +893,12 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, case 0: return true; case WireFormatLite::kMessageSetItemStartTag: - if (!ParseMessageSetItem(input, containing_type, field_skipper)) { + if (!ParseMessageSetItem(input, extension_finder, field_skipper)) { return false; } break; default: - if (!ParseField(tag, input, containing_type, field_skipper)) { + if (!ParseField(tag, input, extension_finder, field_skipper)) { return false; } break; @@ -870,7 +909,8 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, const MessageLite* containing_type) { FieldSkipper skipper; - return ParseMessageSet(input, containing_type, &skipper); + GeneratedExtensionFinder finder(containing_type); + return ParseMessageSet(input, &finder, &skipper); } // Defined in extension_set_heavy.cc. @@ -879,7 +919,7 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, // UnknownFieldSet* unknown_fields); bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, - const MessageLite* containing_type, + ExtensionFinder* extension_finder, FieldSkipper* field_skipper) { // TODO(kenton): It would be nice to share code between this and // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the @@ -919,7 +959,7 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, reinterpret_cast<const uint8*>(message_data.data()), message_data.size()); if (!ParseField(fake_tag, &sub_input, - containing_type, field_skipper)) { + extension_finder, field_skipper)) { return false; } message_data.clear(); @@ -939,7 +979,7 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, } else { // Already saw type_id, so we can parse this directly. if (!ParseField(fake_tag, input, - containing_type, field_skipper)) { + extension_finder, field_skipper)) { return false; } } @@ -969,26 +1009,6 @@ void ExtensionSet::SerializeWithCachedSizes( } } -uint8* ExtensionSet::SerializeWithCachedSizesToArray( - int start_field_number, int end_field_number, - uint8* target) const { - // For now, just create an array output stream around the target and dispatch - // to SerializeWithCachedSizes(). Give the array output stream kint32max - // bytes; we will certainly write less than that. It is up to the caller to - // ensure that the buffer has sufficient space. - int written_bytes; - { - io::ArrayOutputStream array_stream(target, kint32max); - io::CodedOutputStream output_stream(&array_stream); - SerializeWithCachedSizes(start_field_number, - end_field_number, - &output_stream); - written_bytes = output_stream.ByteCount(); - GOOGLE_DCHECK(!output_stream.HadError()); - } - return target + written_bytes; -} - void ExtensionSet::SerializeMessageSetWithCachedSizes( io::CodedOutputStream* output) const { map<int, Extension>::const_iterator iter; @@ -997,23 +1017,6 @@ void ExtensionSet::SerializeMessageSetWithCachedSizes( } } -uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( - uint8* target) const { - // For now, just create an array output stream around the target and dispatch - // to SerializeWithCachedSizes(). Give the array output stream kint32max - // bytes; we will certainly write less than that. It is up to the caller to - // ensure that the buffer has sufficient space. - int written_bytes; - { - io::ArrayOutputStream array_stream(target, kint32max); - io::CodedOutputStream output_stream(&array_stream); - SerializeMessageSetWithCachedSizes(&output_stream); - written_bytes = output_stream.ByteCount(); - GOOGLE_DCHECK(!output_stream.HadError()); - } - return target + written_bytes; -} - int ExtensionSet::ByteSize() const { int total_size = 0; @@ -1039,10 +1042,13 @@ int ExtensionSet::MessageSetByteSize() const { // Defined in extension_set_heavy.cc. // int ExtensionSet::SpaceUsedExcludingSelf() const -bool ExtensionSet::MaybeNewExtension(int number, Extension** result) { +bool ExtensionSet::MaybeNewExtension(int number, + const FieldDescriptor* descriptor, + Extension** result) { pair<map<int, Extension>::iterator, bool> insert_result = extensions_.insert(make_pair(number, Extension())); *result = &insert_result.first->second; + (*result)->descriptor = descriptor; return insert_result.second; } @@ -1206,20 +1212,20 @@ void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes( if (is_cleared) return; // Start group. - output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); + output->WriteTag(WireFormatLite::kMessageSetItemStartTag); // Write type ID. - output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); - output->WriteVarint32(number); - + WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber, + number, + output); // Write message. - output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); - - output->WriteVarint32(message_value->GetCachedSize()); - message_value->SerializeWithCachedSizes(output); + WireFormatLite::WriteMessageMaybeToArray( + WireFormatLite::kMessageSetMessageNumber, + *message_value, + output); // End group. - output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); + output->WriteTag(WireFormatLite::kMessageSetItemEndTag); } int ExtensionSet::Extension::ByteSize(int number) const { diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index e5ac277..14d5d15 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -53,6 +53,7 @@ namespace protobuf { class FieldDescriptor; // descriptor.h class DescriptorPool; // descriptor.h class MessageLite; // message_lite.h + class Message; // message.h class MessageFactory; // message.h class UnknownFieldSet; // unknown_field_set.h namespace io { @@ -76,6 +77,70 @@ namespace internal { // ExtensionSet::Extension small. typedef uint8 FieldType; +// A function which, given an integer value, returns true if the number +// matches one of the defined values for the corresponding enum type. This +// is used with RegisterEnumExtension, below. +typedef bool EnumValidityFunc(int number); + +// Version of the above which takes an argument. This is needed to deal with +// extensions that are not compiled in. +typedef bool EnumValidityFuncWithArg(const void* arg, int number); + +// Information about a registered extension. +struct ExtensionInfo { + inline ExtensionInfo() {} + inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed) + : type(type), is_repeated(is_repeated), is_packed(is_packed), + descriptor(NULL) {} + + FieldType type; + bool is_repeated; + bool is_packed; + + struct EnumValidityCheck { + EnumValidityFuncWithArg* func; + const void* arg; + }; + + union { + EnumValidityCheck enum_validity_check; + const MessageLite* message_prototype; + }; + + // The descriptor for this extension, if one exists and is known. May be + // NULL. Must not be NULL if the descriptor for the extension does not + // live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor; +}; + +// Abstract interface for an object which looks up extension definitions. Used +// when parsing. +class LIBPROTOBUF_EXPORT ExtensionFinder { + public: + virtual ~ExtensionFinder(); + + // Find the extension with the given containing type and number. + virtual bool Find(int number, ExtensionInfo* output) = 0; +}; + +// Implementation of ExtensionFinder which finds extensions defined in .proto +// files which have been compiled into the binary. +class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder { + public: + GeneratedExtensionFinder(const MessageLite* containing_type) + : containing_type_(containing_type) {} + virtual ~GeneratedExtensionFinder() {} + + // Returns true and fills in *output if found, otherwise returns false. + virtual bool Find(int number, ExtensionInfo* output); + + private: + const MessageLite* containing_type_; +}; + +// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for +// finding extensions from a DescriptorPool. + // This is an internal helper class intended for use within the protocol buffer // library and generated classes. Clients should not use it directly. Instead, // use the generated accessors such as GetExtension() of the class being @@ -92,11 +157,6 @@ class LIBPROTOBUF_EXPORT ExtensionSet { ExtensionSet(); ~ExtensionSet(); - // A function which, given an integer value, returns true if the number - // matches one of the defined values for the corresponding enum type. This - // is used with RegisterEnumExtension, below. - typedef bool EnumValidityFunc(int number); - // These are called at startup by protocol-compiler-generated code to // register known extensions. The registrations are used by ParseField() // to look up extensions for parsed field numbers. Note that dynamic parsing @@ -117,11 +177,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // ================================================================= // Add all fields which are currently present to the given vector. This - // is useful to implement Reflection::ListFields(). The FieldDescriptors - // are looked up by number from the given pool. - // - // TODO(kenton): Looking up each field by number is somewhat unfortunate. - // Is there a better way? + // is useful to implement Reflection::ListFields(). void AppendToList(const Descriptor* containing_type, const DescriptorPool* pool, vector<const FieldDescriptor*>* output) const; @@ -176,21 +232,25 @@ class LIBPROTOBUF_EXPORT ExtensionSet { const MessageLite& GetMessage(int number, const Descriptor* message_type, MessageFactory* factory) const; - void SetInt32 (int number, FieldType type, int32 value); - void SetInt64 (int number, FieldType type, int64 value); - void SetUInt32(int number, FieldType type, uint32 value); - void SetUInt64(int number, FieldType type, uint64 value); - void SetFloat (int number, FieldType type, float value); - void SetDouble(int number, FieldType type, double value); - void SetBool (int number, FieldType type, bool value); - void SetEnum (int number, FieldType type, int value); - void SetString(int number, FieldType type, const string& value); - string * MutableString (int number, FieldType type); + // |descriptor| may be NULL so long as it is known that the descriptor for + // the extension lives in the same pool as the descriptor for the containing + // type. +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void SetInt32 (int number, FieldType type, int32 value, desc); + void SetInt64 (int number, FieldType type, int64 value, desc); + void SetUInt32(int number, FieldType type, uint32 value, desc); + void SetUInt64(int number, FieldType type, uint64 value, desc); + void SetFloat (int number, FieldType type, float value, desc); + void SetDouble(int number, FieldType type, double value, desc); + void SetBool (int number, FieldType type, bool value, desc); + void SetEnum (int number, FieldType type, int value, desc); + void SetString(int number, FieldType type, const string& value, desc); + string * MutableString (int number, FieldType type, desc); MessageLite* MutableMessage(int number, FieldType type, - const MessageLite& prototype); - MessageLite* MutableMessage(int number, FieldType type, - const Descriptor* message_type, + const MessageLite& prototype, desc); + MessageLite* MutableMessage(const FieldDescriptor* decsriptor, MessageFactory* factory); +#undef desc // repeated fields ------------------------------------------------- @@ -217,21 +277,22 @@ class LIBPROTOBUF_EXPORT ExtensionSet { string * MutableRepeatedString (int number, int index); MessageLite* MutableRepeatedMessage(int number, int index); - void AddInt32 (int number, FieldType type, bool packed, int32 value); - void AddInt64 (int number, FieldType type, bool packed, int64 value); - void AddUInt32(int number, FieldType type, bool packed, uint32 value); - void AddUInt64(int number, FieldType type, bool packed, uint64 value); - void AddFloat (int number, FieldType type, bool packed, float value); - void AddDouble(int number, FieldType type, bool packed, double value); - void AddBool (int number, FieldType type, bool packed, bool value); - void AddEnum (int number, FieldType type, bool packed, int value); - void AddString(int number, FieldType type, const string& value); - string * AddString (int number, FieldType type); - MessageLite* AddMessage(int number, FieldType type, - const MessageLite& prototype); +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void AddInt32 (int number, FieldType type, bool packed, int32 value, desc); + void AddInt64 (int number, FieldType type, bool packed, int64 value, desc); + void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc); + void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc); + void AddFloat (int number, FieldType type, bool packed, float value, desc); + void AddDouble(int number, FieldType type, bool packed, double value, desc); + void AddBool (int number, FieldType type, bool packed, bool value, desc); + void AddEnum (int number, FieldType type, bool packed, int value, desc); + void AddString(int number, FieldType type, const string& value, desc); + string * AddString (int number, FieldType type, desc); MessageLite* AddMessage(int number, FieldType type, - const Descriptor* message_type, + const MessageLite& prototype, desc); + MessageLite* AddMessage(const FieldDescriptor* descriptor, MessageFactory* factory); +#undef desc void RemoveLast(int number); void SwapElements(int number, int index1, int index2); @@ -257,7 +318,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // methods of ExtensionSet, this only works for generated message types -- // it looks up extensions registered using RegisterExtension(). bool ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type, + ExtensionFinder* extension_finder, FieldSkipper* field_skipper); // Specific versions for lite or full messages (constructs the appropriate @@ -265,13 +326,13 @@ class LIBPROTOBUF_EXPORT ExtensionSet { bool ParseField(uint32 tag, io::CodedInputStream* input, const MessageLite* containing_type); bool ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type, + const Message* containing_type, UnknownFieldSet* unknown_fields); // Parse an entire message in MessageSet format. Such messages have no // fields, only extensions. bool ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type, + ExtensionFinder* extension_finder, FieldSkipper* field_skipper); // Specific versions for lite or full messages (constructs the appropriate @@ -279,7 +340,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { bool ParseMessageSet(io::CodedInputStream* input, const MessageLite* containing_type); bool ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type, + const Message* containing_type, UnknownFieldSet* unknown_fields); // Write all extension fields with field numbers in the range @@ -359,6 +420,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // For repeated types, this indicates if the [packed=true] option is set. bool is_packed; + // The descriptor for this extension, if one exists and is known. May be + // NULL. Must not be NULL if the descriptor for the extension does not + // live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor; + // For packed fields, the size of the packed data is recorded here when // ByteSize() is called then used during serialization. // TODO(kenton): Use atomic<int> when C++ supports it. @@ -368,9 +434,15 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void SerializeFieldWithCachedSizes( int number, io::CodedOutputStream* output) const; + uint8* SerializeFieldWithCachedSizesToArray( + int number, + uint8* target) const; void SerializeMessageSetItemWithCachedSizes( int number, io::CodedOutputStream* output) const; + uint8* SerializeMessageSetItemWithCachedSizesToArray( + int number, + uint8* target) const; int ByteSize(int number) const; int MessageSetItemByteSize(int number) const; void Clear(); @@ -381,14 +453,16 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // Gets the extension with the given number, creating it if it does not // already exist. Returns true if the extension did not already exist. - bool MaybeNewExtension(int number, Extension** result); + bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, + Extension** result); // Parse a single MessageSet item -- called just after the item group start // tag has been read. bool ParseMessageSetItem(io::CodedInputStream* input, - const MessageLite* containing_type, + ExtensionFinder* extension_finder, FieldSkipper* field_skipper); + // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This // friendship should automatically extend to ExtensionSet::Extension, but // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this @@ -412,16 +486,18 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // These are just for convenience... inline void ExtensionSet::SetString(int number, FieldType type, - const string& value) { - MutableString(number, type)->assign(value); + const string& value, + const FieldDescriptor* descriptor) { + MutableString(number, type, descriptor)->assign(value); } inline void ExtensionSet::SetRepeatedString(int number, int index, const string& value) { MutableRepeatedString(number, index)->assign(value); } inline void ExtensionSet::AddString(int number, FieldType type, - const string& value) { - AddString(number, type)->assign(value); + const string& value, + const FieldDescriptor* descriptor) { + AddString(number, type, descriptor)->assign(value); } // =================================================================== @@ -502,7 +578,7 @@ template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get( \ } \ template<> inline void PrimitiveTypeTraits<TYPE>::Set( \ int number, FieldType field_type, TYPE value, ExtensionSet* set) { \ - set->Set##METHOD(number, field_type, value); \ + set->Set##METHOD(number, field_type, value, NULL); \ } \ \ template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \ @@ -516,7 +592,7 @@ template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \ template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \ int number, FieldType field_type, bool is_packed, \ TYPE value, ExtensionSet* set) { \ - set->Add##METHOD(number, field_type, is_packed, value); \ + set->Add##METHOD(number, field_type, is_packed, value, NULL); \ } PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32) @@ -544,11 +620,11 @@ class LIBPROTOBUF_EXPORT StringTypeTraits { } static inline void Set(int number, FieldType field_type, const string& value, ExtensionSet* set) { - set->SetString(number, field_type, value); + set->SetString(number, field_type, value, NULL); } static inline string* Mutable(int number, FieldType field_type, ExtensionSet* set) { - return set->MutableString(number, field_type); + return set->MutableString(number, field_type, NULL); } }; @@ -571,11 +647,11 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { static inline void Add(int number, FieldType field_type, bool /*is_packed*/, const string& value, ExtensionSet* set) { - set->AddString(number, field_type, value); + set->AddString(number, field_type, value, NULL); } static inline string* Add(int number, FieldType field_type, ExtensionSet* set) { - return set->AddString(number, field_type); + return set->AddString(number, field_type, NULL); } }; @@ -596,7 +672,7 @@ class EnumTypeTraits { static inline void Set(int number, FieldType field_type, ConstType value, ExtensionSet* set) { GOOGLE_DCHECK(IsValid(value)); - set->SetEnum(number, field_type, value); + set->SetEnum(number, field_type, value, NULL); } }; @@ -616,7 +692,7 @@ class RepeatedEnumTypeTraits { static inline void Add(int number, FieldType field_type, bool is_packed, ConstType value, ExtensionSet* set) { GOOGLE_DCHECK(IsValid(value)); - set->AddEnum(number, field_type, is_packed, value); + set->AddEnum(number, field_type, is_packed, value, NULL); } }; @@ -640,7 +716,7 @@ class MessageTypeTraits { static inline MutableType Mutable(int number, FieldType field_type, ExtensionSet* set) { return static_cast<Type*>( - set->MutableMessage(number, field_type, Type::default_instance())); + set->MutableMessage(number, field_type, Type::default_instance(), NULL)); } }; @@ -659,7 +735,7 @@ class RepeatedMessageTypeTraits { static inline MutableType Add(int number, FieldType field_type, ExtensionSet* set) { return static_cast<Type*>( - set->AddMessage(number, field_type, Type::default_instance())); + set->AddMessage(number, field_type, Type::default_instance(), NULL)); } }; diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 8555f6f..2721f15 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -40,11 +40,31 @@ #include <google/protobuf/message.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite_inl.h> namespace google { namespace protobuf { namespace internal { +// Implementation of ExtensionFinder which finds extensions in a given +// DescriptorPool, using the given MessageFactory to construct sub-objects. +// This class is implemented in extension_set_heavy.cc. +class DescriptorPoolExtensionFinder : public ExtensionFinder { + public: + DescriptorPoolExtensionFinder(const DescriptorPool* pool, + MessageFactory* factory, + const Descriptor* containing_type) + : pool_(pool), factory_(factory), containing_type_(containing_type) {} + virtual ~DescriptorPoolExtensionFinder() {} + + virtual bool Find(int number, ExtensionInfo* output); + + private: + const DescriptorPool* pool_; + MessageFactory* factory_; + const Descriptor* containing_type_; +}; + void ExtensionSet::AppendToList(const Descriptor* containing_type, const DescriptorPool* pool, vector<const FieldDescriptor*>* output) const { @@ -58,12 +78,26 @@ void ExtensionSet::AppendToList(const Descriptor* containing_type, } if (has) { - output->push_back( - pool->FindExtensionByNumber(containing_type, iter->first)); + // TODO(kenton): Looking up each field by number is somewhat unfortunate. + // Is there a better way? The problem is that descriptors are lazily- + // initialized, so they might not even be constructed until + // AppendToList() is called. + + if (iter->second.descriptor == NULL) { + output->push_back(pool->FindExtensionByNumber( + containing_type, iter->first)); + } else { + output->push_back(iter->second.descriptor); + } } } } +inline FieldDescriptor::Type real_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE); + return static_cast<FieldDescriptor::Type>(type); +} + inline FieldDescriptor::CppType cpp_type(FieldType type) { return FieldDescriptor::TypeToCppType( static_cast<FieldDescriptor::Type>(type)); @@ -88,16 +122,16 @@ const MessageLite& ExtensionSet::GetMessage(int number, } } -MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, - const Descriptor* message_type, +MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor, MessageFactory* factory) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { - extension->type = type; + if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { + extension->type = descriptor->type(); GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); extension->is_repeated = false; extension->is_packed = false; - const MessageLite* prototype = factory->GetPrototype(message_type); + const MessageLite* prototype = + factory->GetPrototype(descriptor->message_type()); GOOGLE_CHECK(prototype != NULL); extension->message_value = prototype->New(); } else { @@ -107,12 +141,11 @@ MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, return extension->message_value; } -MessageLite* ExtensionSet::AddMessage(int number, FieldType type, - const Descriptor* message_type, +MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, MessageFactory* factory) { Extension* extension; - if (MaybeNewExtension(number, &extension)) { - extension->type = type; + if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { + extension->type = descriptor->type(); GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); extension->is_repeated = true; extension->repeated_message_value = @@ -128,7 +161,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type, if (result == NULL) { const MessageLite* prototype; if (extension->repeated_message_value->size() == 0) { - prototype = factory->GetPrototype(message_type); + prototype = factory->GetPrototype(descriptor->message_type()); GOOGLE_CHECK(prototype != NULL); } else { prototype = &extension->repeated_message_value->Get(0); @@ -139,18 +172,64 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type, return result; } +static bool ValidateEnumUsingDescriptor(const void* arg, int number) { + return reinterpret_cast<const EnumDescriptor*>(arg) + ->FindValueByNumber(number) != NULL; +} + +bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { + const FieldDescriptor* extension = + pool_->FindExtensionByNumber(containing_type_, number); + if (extension == NULL) { + return false; + } else { + output->type = extension->type(); + output->is_repeated = extension->is_repeated(); + output->is_packed = extension->options().packed(); + output->descriptor = extension; + if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + output->message_prototype = + factory_->GetPrototype(extension->message_type()); + GOOGLE_CHECK(output->message_prototype != NULL) + << "Extension factory's GetPrototype() returned NULL for extension: " + << extension->full_name(); + } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + output->enum_validity_check.func = ValidateEnumUsingDescriptor; + output->enum_validity_check.arg = extension->enum_type(); + } + + return true; + } +} + bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const MessageLite* containing_type, + const Message* containing_type, UnknownFieldSet* unknown_fields) { UnknownFieldSetFieldSkipper skipper(unknown_fields); - return ParseField(tag, input, containing_type, &skipper); + if (input->GetExtensionPool() == NULL) { + GeneratedExtensionFinder finder(containing_type); + return ParseField(tag, input, &finder, &skipper); + } else { + DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), + input->GetExtensionFactory(), + containing_type->GetDescriptor()); + return ParseField(tag, input, &finder, &skipper); + } } bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, - const MessageLite* containing_type, + const Message* containing_type, UnknownFieldSet* unknown_fields) { UnknownFieldSetFieldSkipper skipper(unknown_fields); - return ParseMessageSet(input, containing_type, &skipper); + if (input->GetExtensionPool() == NULL) { + GeneratedExtensionFinder finder(containing_type); + return ParseMessageSet(input, &finder, &skipper); + } else { + DescriptorPoolExtensionFinder finder(input->GetExtensionPool(), + input->GetExtensionFactory(), + containing_type->GetDescriptor()); + return ParseMessageSet(input, &finder, &skipper); + } } int ExtensionSet::SpaceUsedExcludingSelf() const { @@ -175,7 +254,7 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { if (is_repeated) { switch (cpp_type(type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case WireFormatLite::CPPTYPE_##UPPERCASE: \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ total_size += sizeof(*repeated_##LOWERCASE##_value) + \ repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\ break @@ -189,8 +268,9 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { HANDLE_TYPE( BOOL, bool); HANDLE_TYPE( ENUM, enum); HANDLE_TYPE( STRING, string); +#undef HANDLE_TYPE - case WireFormatLite::CPPTYPE_MESSAGE: + case FieldDescriptor::CPPTYPE_MESSAGE: // repeated_message_value is actually a RepeatedPtrField<MessageLite>, // but MessageLite has no SpaceUsed(), so we must directly call // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type @@ -201,11 +281,11 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { } } else { switch (cpp_type(type)) { - case WireFormatLite::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_STRING: total_size += sizeof(*string_value) + StringSpaceUsedExcludingSelf(*string_value); break; - case WireFormatLite::CPPTYPE_MESSAGE: + case FieldDescriptor::CPPTYPE_MESSAGE: total_size += down_cast<Message*>(message_value)->SpaceUsed(); break; default: @@ -216,6 +296,162 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { return total_size; } +// The Serialize*ToArray methods are only needed in the heavy library, as +// the lite library only generates SerializeWithCachedSizes. +uint8* ExtensionSet::SerializeWithCachedSizesToArray( + int start_field_number, int end_field_number, + uint8* target) const { + map<int, Extension>::const_iterator iter; + for (iter = extensions_.lower_bound(start_field_number); + iter != extensions_.end() && iter->first < end_field_number; + ++iter) { + target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first, + target); + } + return target; +} + +uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( + uint8* target) const { + map<int, Extension>::const_iterator iter; + for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { + target = iter->second.SerializeMessageSetItemWithCachedSizesToArray( + iter->first, target); + } + return target; +} + +uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray( + int number, uint8* target) const { + if (is_repeated) { + if (is_packed) { + if (cached_size == 0) return target; + + target = WireFormatLite::WriteTagToArray(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target); + target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target); + + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case FieldDescriptor::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \ + repeated_##LOWERCASE##_value->Get(i), target); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); + HANDLE_TYPE( ENUM, Enum, enum); +#undef HANDLE_TYPE + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; + break; + } + } else { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ + case FieldDescriptor::TYPE_##UPPERCASE: \ + for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ + target = WireFormatLite::Write##CAMELCASE##ToArray(number, \ + repeated_##LOWERCASE##_value->Get(i), target); \ + } \ + break + + HANDLE_TYPE( INT32, Int32, int32); + HANDLE_TYPE( INT64, Int64, int64); + HANDLE_TYPE( UINT32, UInt32, uint32); + HANDLE_TYPE( UINT64, UInt64, uint64); + HANDLE_TYPE( SINT32, SInt32, int32); + HANDLE_TYPE( SINT64, SInt64, int64); + HANDLE_TYPE( FIXED32, Fixed32, uint32); + HANDLE_TYPE( FIXED64, Fixed64, uint64); + HANDLE_TYPE(SFIXED32, SFixed32, int32); + HANDLE_TYPE(SFIXED64, SFixed64, int64); + HANDLE_TYPE( FLOAT, Float, float); + HANDLE_TYPE( DOUBLE, Double, double); + HANDLE_TYPE( BOOL, Bool, bool); + HANDLE_TYPE( STRING, String, string); + HANDLE_TYPE( BYTES, Bytes, string); + HANDLE_TYPE( ENUM, Enum, enum); + HANDLE_TYPE( GROUP, Group, message); + HANDLE_TYPE( MESSAGE, Message, message); +#undef HANDLE_TYPE + } + } + } else if (!is_cleared) { + switch (real_type(type)) { +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ + case FieldDescriptor::TYPE_##UPPERCASE: \ + target = WireFormatLite::Write##CAMELCASE##ToArray( \ + number, VALUE, target); \ + break + + HANDLE_TYPE( INT32, Int32, int32_value); + HANDLE_TYPE( INT64, Int64, int64_value); + HANDLE_TYPE( UINT32, UInt32, uint32_value); + HANDLE_TYPE( UINT64, UInt64, uint64_value); + HANDLE_TYPE( SINT32, SInt32, int32_value); + HANDLE_TYPE( SINT64, SInt64, int64_value); + HANDLE_TYPE( FIXED32, Fixed32, uint32_value); + HANDLE_TYPE( FIXED64, Fixed64, uint64_value); + HANDLE_TYPE(SFIXED32, SFixed32, int32_value); + HANDLE_TYPE(SFIXED64, SFixed64, int64_value); + HANDLE_TYPE( FLOAT, Float, float_value); + HANDLE_TYPE( DOUBLE, Double, double_value); + HANDLE_TYPE( BOOL, Bool, bool_value); + HANDLE_TYPE( STRING, String, *string_value); + HANDLE_TYPE( BYTES, Bytes, *string_value); + HANDLE_TYPE( ENUM, Enum, enum_value); + HANDLE_TYPE( GROUP, Group, *message_value); + HANDLE_TYPE( MESSAGE, Message, *message_value); +#undef HANDLE_TYPE + } + } + return target; +} + +uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray( + int number, + uint8* target) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but serialize it the normal way. + GOOGLE_LOG(WARNING) << "Invalid message set extension."; + return SerializeFieldWithCachedSizesToArray(number, target); + } + + if (is_cleared) return target; + + // Start group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemStartTag, target); + // Write type ID. + target = WireFormatLite::WriteUInt32ToArray( + WireFormatLite::kMessageSetTypeIdNumber, number, target); + // Write message. + target = WireFormatLite::WriteMessageToArray( + WireFormatLite::kMessageSetMessageNumber, *message_value, target); + // End group. + target = io::CodedOutputStream::WriteTagToArray( + WireFormatLite::kMessageSetItemEndTag, target); + return target; +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index 327aee0..000f846 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -35,10 +35,15 @@ #include <google/protobuf/extension_set.h> #include <google/protobuf/unittest.pb.h> #include <google/protobuf/test_util.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/wire_format.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/testing/googletest.h> #include <gtest/gtest.h> #include <google/protobuf/stubs/stl_util-inl.h> @@ -477,6 +482,160 @@ TEST(ExtensionSetTest, InvalidEnumDeath) { #endif // GTEST_HAS_DEATH_TEST +TEST(ExtensionSetTest, DynamicExtensions) { + // Test adding a dynamic extension to a compiled-in message object. + + FileDescriptorProto dynamic_proto; + dynamic_proto.set_name("dynamic_extensions_test.proto"); + dynamic_proto.add_dependency( + unittest::TestAllExtensions::descriptor()->file()->name()); + dynamic_proto.set_package("dynamic_extensions"); + + // Copy the fields and nested types from TestDynamicExtensions into our new + // proto, converting the fields into extensions. + const Descriptor* template_descriptor = + unittest::TestDynamicExtensions::descriptor(); + DescriptorProto template_descriptor_proto; + template_descriptor->CopyTo(&template_descriptor_proto); + dynamic_proto.mutable_message_type()->MergeFrom( + template_descriptor_proto.nested_type()); + dynamic_proto.mutable_enum_type()->MergeFrom( + template_descriptor_proto.enum_type()); + dynamic_proto.mutable_extension()->MergeFrom( + template_descriptor_proto.field()); + + // For each extension that we added... + for (int i = 0; i < dynamic_proto.extension_size(); i++) { + // Set its extendee to TestAllExtensions. + FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i); + extension->set_extendee( + unittest::TestAllExtensions::descriptor()->full_name()); + + // If the field refers to one of the types nested in TestDynamicExtensions, + // make it refer to the type in our dynamic proto instead. + string prefix = "." + template_descriptor->full_name() + "."; + if (extension->has_type_name()) { + string* type_name = extension->mutable_type_name(); + if (HasPrefixString(*type_name, prefix)) { + type_name->replace(0, prefix.size(), ".dynamic_extensions."); + } + } + } + + // Now build the file, using the generated pool as an underlay. + DescriptorPool dynamic_pool(DescriptorPool::generated_pool()); + const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto); + ASSERT_TRUE(file != NULL); + DynamicMessageFactory dynamic_factory(&dynamic_pool); + dynamic_factory.SetDelegateToGeneratedFactory(true); + + // Construct a message that we can parse with the extensions we defined. + // Since the extensions were based off of the fields of TestDynamicExtensions, + // we can use that message to create this test message. + string data; + { + unittest::TestDynamicExtensions message; + message.set_scalar_extension(123); + message.set_enum_extension(unittest::FOREIGN_BAR); + message.set_dynamic_enum_extension( + unittest::TestDynamicExtensions::DYNAMIC_BAZ); + message.mutable_message_extension()->set_c(456); + message.mutable_dynamic_message_extension()->set_dynamic_field(789); + message.add_repeated_extension("foo"); + message.add_repeated_extension("bar"); + message.add_packed_extension(12); + message.add_packed_extension(-34); + message.add_packed_extension(56); + message.add_packed_extension(-78); + + // Also add some unknown fields. + + // An unknown enum value (for a known field). + message.mutable_unknown_fields()->AddVarint( + unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber, + 12345); + // A regular unknown field. + message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown"); + + message.SerializeToString(&data); + } + + // Now we can parse this using our dynamic extension definitions... + unittest::TestAllExtensions message; + { + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory); + ASSERT_TRUE(message.ParseFromCodedStream(&input)); + ASSERT_TRUE(input.ConsumedEntireMessage()); + } + + // Can we print it? + EXPECT_EQ( + "[dynamic_extensions.scalar_extension]: 123\n" + "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n" + "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n" + "[dynamic_extensions.message_extension] {\n" + " c: 456\n" + "}\n" + "[dynamic_extensions.dynamic_message_extension] {\n" + " dynamic_field: 789\n" + "}\n" + "[dynamic_extensions.repeated_extension]: \"foo\"\n" + "[dynamic_extensions.repeated_extension]: \"bar\"\n" + "[dynamic_extensions.packed_extension]: 12\n" + "[dynamic_extensions.packed_extension]: -34\n" + "[dynamic_extensions.packed_extension]: 56\n" + "[dynamic_extensions.packed_extension]: -78\n" + "2002: 12345\n" + "54321: \"unknown\"\n", + message.DebugString()); + + // Can we serialize it? + // (Don't use EXPECT_EQ because we don't want to dump raw binary data to the + // terminal on failure.) + EXPECT_TRUE(message.SerializeAsString() == data); + + // What if we parse using the reflection-based parser? + { + unittest::TestAllExtensions message2; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory); + ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2)); + ASSERT_TRUE(input.ConsumedEntireMessage()); + EXPECT_EQ(message.DebugString(), message2.DebugString()); + } + + // Are the embedded generated types actually using the generated objects? + { + const FieldDescriptor* message_extension = + file->FindExtensionByName("message_extension"); + ASSERT_TRUE(message_extension != NULL); + const Message& sub_message = + message.GetReflection()->GetMessage(message, message_extension); + const unittest::ForeignMessage* typed_sub_message = + dynamic_cast<const unittest::ForeignMessage*>(&sub_message); + ASSERT_TRUE(typed_sub_message != NULL); + EXPECT_EQ(456, typed_sub_message->c()); + } + + // What does GetMessage() return for the embedded dynamic type if it isn't + // present? + { + const FieldDescriptor* dynamic_message_extension = + file->FindExtensionByName("dynamic_message_extension"); + ASSERT_TRUE(dynamic_message_extension != NULL); + const Message& parent = unittest::TestAllExtensions::default_instance(); + const Message& sub_message = + parent.GetReflection()->GetMessage(parent, dynamic_message_extension, + &dynamic_factory); + const Message* prototype = + dynamic_factory.GetPrototype(dynamic_message_extension->message_type()); + EXPECT_EQ(prototype, &sub_message); + } +} + } // namespace } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index d294e58..0f065ff 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -239,8 +239,13 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const { #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_STRING: - total_size += GetRaw<RepeatedPtrField<string> >(message, field) - .SpaceUsedExcludingSelf(); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + total_size += GetRaw<RepeatedPtrField<string> >(message, field) + .SpaceUsedExcludingSelf(); + break; + } break; case FieldDescriptor::CPPTYPE_MESSAGE: @@ -265,18 +270,24 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const { break; case FieldDescriptor::CPPTYPE_STRING: { - const string* ptr = GetField<const string*>(message, field); - - // Initially, the string points to the default value stored in - // the prototype. Only count the string if it has been changed - // from the default value. - const string* default_ptr = DefaultRaw<const string*>(field); - - if (ptr != default_ptr) { - // string fields are represented by just a pointer, so also - // include sizeof(string) as well. - total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + const string* ptr = GetField<const string*>(message, field); + + // Initially, the string points to the default value stored in + // the prototype. Only count the string if it has been changed + // from the default value. + const string* default_ptr = DefaultRaw<const string*>(field); + + if (ptr != default_ptr) { + // string fields are represented by just a pointer, so also + // include sizeof(string) as well. + total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); + } + break; } + } break; } @@ -324,7 +335,7 @@ void GeneratedMessageReflection::Swap( int has_bits_size = (descriptor_->field_count() + 31) / 32; for (int i = 0; i < has_bits_size; i++) { - swap(has_bits1[i], has_bits2[i]); + std::swap(has_bits1[i], has_bits2[i]); } for (int i = 0; i < descriptor_->field_count(); i++) { @@ -360,8 +371,8 @@ void GeneratedMessageReflection::Swap( switch (field->cpp_type()) { #define SWAP_VALUES(CPPTYPE, TYPE) \ case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - swap(*MutableRaw<TYPE>(message1, field), \ - *MutableRaw<TYPE>(message2, field)); \ + std::swap(*MutableRaw<TYPE>(message1, field), \ + *MutableRaw<TYPE>(message2, field)); \ break; SWAP_VALUES(INT32 , int32 ); @@ -376,8 +387,13 @@ void GeneratedMessageReflection::Swap( #undef SWAP_VALUES case FieldDescriptor::CPPTYPE_STRING: - swap(*MutableRaw<string*>(message1, field), - *MutableRaw<string*>(message2, field)); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + std::swap(*MutableRaw<string*>(message1, field), + *MutableRaw<string*>(message2, field)); + break; + } break; default: @@ -473,15 +489,20 @@ void GeneratedMessageReflection::ClearField( break; case FieldDescriptor::CPPTYPE_STRING: { - const string* default_ptr = DefaultRaw<const string*>(field); - string** value = MutableRaw<string*>(message, field); - if (*value != default_ptr) { - if (field->has_default_value()) { - (*value)->assign(field->default_value_string()); - } else { - (*value)->clear(); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + const string* default_ptr = DefaultRaw<const string*>(field); + string** value = MutableRaw<string*>(message, field); + if (*value != default_ptr) { + if (field->has_default_value()) { + (*value)->assign(field->default_value_string()); + } else { + (*value)->clear(); + } } - } + break; + } break; } @@ -508,7 +529,12 @@ void GeneratedMessageReflection::ClearField( #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_STRING: { - MutableRaw<RepeatedPtrField<string> >(message, field)->Clear(); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + MutableRaw<RepeatedPtrField<string> >(message, field)->Clear(); + break; + } break; } @@ -549,7 +575,12 @@ void GeneratedMessageReflection::RemoveLast( #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_STRING: - MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast(); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast(); + break; + } break; case FieldDescriptor::CPPTYPE_MESSAGE: @@ -658,7 +689,7 @@ void GeneratedMessageReflection::ListFields( USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \ if (field->is_extension()) { \ return MutableExtensionSet(message)->Set##TYPENAME( \ - field->number(), field->type(), value); \ + field->number(), field->type(), value, field); \ } else { \ SetField<TYPE>(message, field, value); \ } \ @@ -694,7 +725,8 @@ void GeneratedMessageReflection::ListFields( USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \ if (field->is_extension()) { \ MutableExtensionSet(message)->Add##TYPENAME( \ - field->number(), field->type(), field->options().packed(), value); \ + field->number(), field->type(), field->options().packed(), value, \ + field); \ } else { \ AddField<TYPE>(message, field, value); \ } \ @@ -718,7 +750,14 @@ string GeneratedMessageReflection::GetString( return GetExtensionSet(message).GetString(field->number(), field->default_value_string()); } else { - return *GetField<const string*>(message, field); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return *GetField<const string*>(message, field); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. } } @@ -730,7 +769,14 @@ const string& GeneratedMessageReflection::GetStringReference( return GetExtensionSet(message).GetString(field->number(), field->default_value_string()); } else { - return *GetField<const string*>(message, field); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return *GetField<const string*>(message, field); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. } } @@ -741,13 +787,19 @@ void GeneratedMessageReflection::SetString( USAGE_CHECK_ALL(SetString, SINGULAR, STRING); if (field->is_extension()) { return MutableExtensionSet(message)->SetString(field->number(), - field->type(), value); + field->type(), value, field); } else { - string** ptr = MutableField<string*>(message, field); - if (*ptr == DefaultRaw<const string*>(field)) { - *ptr = new string(value); - } else { - (*ptr)->assign(value); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: { + string** ptr = MutableField<string*>(message, field); + if (*ptr == DefaultRaw<const string*>(field)) { + *ptr = new string(value); + } else { + (*ptr)->assign(value); + } + break; + } } } } @@ -759,7 +811,14 @@ string GeneratedMessageReflection::GetRepeatedString( if (field->is_extension()) { return GetExtensionSet(message).GetRepeatedString(field->number(), index); } else { - return GetRepeatedPtrField<string>(message, field, index); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return GetRepeatedPtrField<string>(message, field, index); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. } } @@ -770,7 +829,14 @@ const string& GeneratedMessageReflection::GetRepeatedStringReference( if (field->is_extension()) { return GetExtensionSet(message).GetRepeatedString(field->number(), index); } else { - return GetRepeatedPtrField<string>(message, field, index); + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + return GetRepeatedPtrField<string>(message, field, index); + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return kEmptyString; // Make compiler happy. } } @@ -783,7 +849,12 @@ void GeneratedMessageReflection::SetRepeatedString( MutableExtensionSet(message)->SetRepeatedString( field->number(), index, value); } else { - *MutableRepeatedField<string>(message, field, index) = value; + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + *MutableRepeatedField<string>(message, field, index) = value; + break; + } } } @@ -794,9 +865,14 @@ void GeneratedMessageReflection::AddString( USAGE_CHECK_ALL(AddString, REPEATED, STRING); if (field->is_extension()) { MutableExtensionSet(message)->AddString(field->number(), - field->type(), value); + field->type(), value, field); } else { - *AddField<string>(message, field) = value; + switch (field->options().ctype()) { + default: // TODO(kenton): Support other string reps. + case FieldOptions::STRING: + *AddField<string>(message, field) = value; + break; + } } } @@ -828,7 +904,7 @@ void GeneratedMessageReflection::SetEnum( if (field->is_extension()) { MutableExtensionSet(message)->SetEnum(field->number(), field->type(), - value->number()); + value->number(), field); } else { SetField<int>(message, field, value->number()); } @@ -874,7 +950,7 @@ void GeneratedMessageReflection::AddEnum( if (field->is_extension()) { MutableExtensionSet(message)->AddEnum(field->number(), field->type(), field->options().packed(), - value->number()); + value->number(), field); } else { AddField<int>(message, field, value->number()); } @@ -883,14 +959,15 @@ void GeneratedMessageReflection::AddEnum( // ------------------------------------------------------------------- const Message& GeneratedMessageReflection::GetMessage( - const Message& message, const FieldDescriptor* field) const { + const Message& message, const FieldDescriptor* field, + MessageFactory* factory) const { USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); if (field->is_extension()) { return static_cast<const Message&>( - GetExtensionSet(message).GetMessage(field->number(), - field->message_type(), - message_factory_)); + GetExtensionSet(message).GetMessage( + field->number(), field->message_type(), + factory == NULL ? message_factory_ : factory)); } else { const Message* result = GetRaw<const Message*>(message, field); if (result == NULL) { @@ -901,15 +978,14 @@ const Message& GeneratedMessageReflection::GetMessage( } Message* GeneratedMessageReflection::MutableMessage( - Message* message, const FieldDescriptor* field) const { + Message* message, const FieldDescriptor* field, + MessageFactory* factory) const { USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); if (field->is_extension()) { return static_cast<Message*>( - MutableExtensionSet(message)->MutableMessage(field->number(), - field->type(), - field->message_type(), - message_factory_)); + MutableExtensionSet(message)->MutableMessage(field, + factory == NULL ? message_factory_ : factory)); } else { Message** result = MutableField<Message*>(message, field); if (*result == NULL) { @@ -948,15 +1024,15 @@ Message* GeneratedMessageReflection::MutableRepeatedMessage( } Message* GeneratedMessageReflection::AddMessage( - Message* message, const FieldDescriptor* field) const { + Message* message, const FieldDescriptor* field, + MessageFactory* factory) const { USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); + if (factory == NULL) factory = message_factory_; + if (field->is_extension()) { return static_cast<Message*>( - MutableExtensionSet(message)->AddMessage(field->number(), - field->type(), - field->message_type(), - message_factory_)); + MutableExtensionSet(message)->AddMessage(field, factory)); } else { // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't // know how to allocate one. @@ -967,7 +1043,7 @@ Message* GeneratedMessageReflection::AddMessage( // We must allocate a new object. const Message* prototype; if (repeated->size() == 0) { - prototype = message_factory_->GetPrototype(field->message_type()); + prototype = factory->GetPrototype(field->message_type()); } else { prototype = &repeated->Get<GenericTypeHandler<Message> >(0); } @@ -1110,7 +1186,7 @@ inline Type* GeneratedMessageReflection::MutableField( } template <typename Type> -inline Type GeneratedMessageReflection::GetRepeatedField( +inline const Type& GeneratedMessageReflection::GetRepeatedField( const Message& message, const FieldDescriptor* field, int index) const { return GetRaw<RepeatedField<Type> >(message, field).Get(index); } @@ -1138,7 +1214,7 @@ inline Type* GeneratedMessageReflection::MutableRepeatedField( template <typename Type> inline void GeneratedMessageReflection::AddField( - Message* message, const FieldDescriptor* field, Type value) const { + Message* message, const FieldDescriptor* field, const Type& value) const { MutableRaw<RepeatedField<Type> >(message, field)->Add(value); } diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index d0b5b43..b545fa1 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -169,7 +169,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { const EnumValueDescriptor* GetEnum(const Message& message, const FieldDescriptor* field) const; const Message& GetMessage(const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field, + MessageFactory* factory = NULL) const; void SetInt32 (Message* message, const FieldDescriptor* field, int32 value) const; @@ -190,7 +191,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { const string& value) const; void SetEnum (Message* message, const FieldDescriptor* field, const EnumValueDescriptor* value) const; - Message* MutableMessage(Message* message, const FieldDescriptor* field) const; + Message* MutableMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; int32 GetRepeatedInt32 (const Message& message, const FieldDescriptor* field, int index) const; @@ -262,7 +264,8 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { void AddEnum(Message* message, const FieldDescriptor* field, const EnumValueDescriptor* value) const; - Message* AddMessage(Message* message, const FieldDescriptor* field) const; + Message* AddMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; const FieldDescriptor* FindKnownExtensionByName(const string& name) const; const FieldDescriptor* FindKnownExtensionByNumber(int number) const; @@ -314,9 +317,9 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { inline Type* MutableField(Message* message, const FieldDescriptor* field) const; template <typename Type> - inline Type GetRepeatedField(const Message& message, - const FieldDescriptor* field, - int index) const; + inline const Type& GetRepeatedField(const Message& message, + const FieldDescriptor* field, + int index) const; template <typename Type> inline const Type& GetRepeatedPtrField(const Message& message, const FieldDescriptor* field, @@ -331,7 +334,7 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { int index) const; template <typename Type> inline void AddField(Message* message, - const FieldDescriptor* field, Type value) const; + const FieldDescriptor* field, const Type& value) const; template <typename Type> inline Type* AddField(Message* message, const FieldDescriptor* field) const; diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 9470bb0..7ac015d 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -34,10 +34,19 @@ #include <google/protobuf/generated_message_util.h> +#include <limits> + namespace google { namespace protobuf { namespace internal { +double Infinity() { + return std::numeric_limits<double>::infinity(); +} +double NaN() { + return std::numeric_limits<double>::quiet_NaN(); +} + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 80dd028..daa16f7 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -43,21 +43,33 @@ namespace google { namespace protobuf { + namespace io { + class CodedInputStream; // coded_stream.h + } +} + +namespace protobuf { namespace internal { // Annotation for the compiler to emit a deprecation message if a field marked -// with option 'deprecated=true' is used in the code. +// with option 'deprecated=true' is used in the code, or for other things in +// generated code which are deprecated. // // For internal use in the pb.cc files, deprecation warnings are suppressed // there. #undef DEPRECATED_PROTOBUF_FIELD #if !defined(INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION) -# define DEPRECATED_PROTOBUF_FIELD GOOGLE_ATTRIBUTE_DEPRECATED +# define PROTOBUF_DEPRECATED GOOGLE_ATTRIBUTE_DEPRECATED #else -# define DEPRECATED_PROTOBUF_FIELD +# define PROTOBUF_DEPRECATED #endif +// Constants for special floating point values. +LIBPROTOBUF_EXPORT double Infinity(); +LIBPROTOBUF_EXPORT double NaN(); + + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index e17a477..6a91a13 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -38,9 +38,9 @@ // will not cross the end of the buffer, since we can avoid a lot // of branching in this case. -#include <stack> +#include <google/protobuf/io/coded_stream_inl.h> +#include <algorithm> #include <limits.h> -#include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/stl_util-inl.h> @@ -52,11 +52,6 @@ namespace io { namespace { -static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB - -static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB -static const int kDefaultRecursionLimit = 64; - static const int kMaxVarintBytes = 10; static const int kMaxVarint32Bytes = 5; @@ -65,72 +60,28 @@ static const int kMaxVarint32Bytes = 5; // CodedInputStream ================================================== -CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) - : input_(input), - buffer_(NULL), - buffer_size_(0), - total_bytes_read_(0), - overflow_bytes_(0), - last_tag_(0), - legitimate_message_end_(false), - aliasing_enabled_(false), - current_limit_(INT_MAX), - buffer_size_after_limit_(0), - total_bytes_limit_(kDefaultTotalBytesLimit), - total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), - recursion_depth_(0), - recursion_limit_(kDefaultRecursionLimit) { - // Eagerly Refresh() so buffer space is immediately available. - Refresh(); -} - -CodedInputStream::CodedInputStream(const uint8* buffer, int size) - : input_(NULL), - buffer_(buffer), - buffer_size_(size), - total_bytes_read_(size), - overflow_bytes_(0), - last_tag_(0), - legitimate_message_end_(false), - aliasing_enabled_(false), - current_limit_(size), - buffer_size_after_limit_(0), - total_bytes_limit_(kDefaultTotalBytesLimit), - total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), - recursion_depth_(0), - recursion_limit_(kDefaultRecursionLimit) { - // Note that setting current_limit_ == size is important to prevent some - // code paths from trying to access input_ and segfaulting. -} - -CodedInputStream::~CodedInputStream() { - if (input_ != NULL) { - BackUpInputToCurrentPosition(); - } -} - void CodedInputStream::BackUpInputToCurrentPosition() { - int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_; + int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_; if (backup_bytes > 0) { input_->BackUp(backup_bytes); // total_bytes_read_ doesn't include overflow_bytes_. - total_bytes_read_ -= buffer_size_ + buffer_size_after_limit_; - buffer_size_ = 0; + total_bytes_read_ -= BufferSize() + buffer_size_after_limit_; + buffer_end_ = buffer_; buffer_size_after_limit_ = 0; overflow_bytes_ = 0; } } inline void CodedInputStream::RecomputeBufferLimits() { - buffer_size_ += buffer_size_after_limit_; + buffer_end_ += buffer_size_after_limit_; int closest_limit = min(current_limit_, total_bytes_limit_); if (closest_limit < total_bytes_read_) { // The limit position is in the current buffer. We must adjust // the buffer size accordingly. buffer_size_after_limit_ = total_bytes_read_ - closest_limit; - buffer_size_ -= buffer_size_after_limit_; + buffer_end_ -= buffer_size_after_limit_; } else { buffer_size_after_limit_ = 0; } @@ -139,7 +90,7 @@ inline void CodedInputStream::RecomputeBufferLimits() { CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) { // Current position relative to the beginning of the stream. int current_position = total_bytes_read_ - - (buffer_size_ + buffer_size_after_limit_); + (BufferSize() + buffer_size_after_limit_); Limit old_limit = current_limit_; @@ -176,7 +127,7 @@ void CodedInputStream::PopLimit(Limit limit) { int CodedInputStream::BytesUntilLimit() { if (current_limit_ == INT_MAX) return -1; int current_position = total_bytes_read_ - - (buffer_size_ + buffer_size_after_limit_); + (BufferSize() + buffer_size_after_limit_); return current_limit_ - current_position; } @@ -186,7 +137,7 @@ void CodedInputStream::SetTotalBytesLimit( // Make sure the limit isn't already past, since this could confuse other // code. int current_position = total_bytes_read_ - - (buffer_size_ + buffer_size_after_limit_); + (BufferSize() + buffer_size_after_limit_); total_bytes_limit_ = max(current_position, total_bytes_limit); total_bytes_warning_threshold_ = warning_threshold; RecomputeBufferLimits(); @@ -203,7 +154,9 @@ void CodedInputStream::PrintTotalBytesLimitError() { bool CodedInputStream::Skip(int count) { if (count < 0) return false; // security: count is often user-supplied - if (count <= buffer_size_) { + const int original_buffer_size = BufferSize(); + + if (count <= original_buffer_size) { // Just skipping within the current buffer. Easy. Advance(count); return true; @@ -211,13 +164,13 @@ bool CodedInputStream::Skip(int count) { if (buffer_size_after_limit_ > 0) { // We hit a limit inside this buffer. Advance to the limit and fail. - Advance(buffer_size_); + Advance(original_buffer_size); return false; } - count -= buffer_size_; + count -= original_buffer_size; buffer_ = NULL; - buffer_size_ = 0; + buffer_end_ = buffer_; // Make sure this skip doesn't try to skip past the current limit. int closest_limit = min(current_limit_, total_bytes_limit_); @@ -236,20 +189,21 @@ bool CodedInputStream::Skip(int count) { } bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) { - if (buffer_size_ == 0 && !Refresh()) return false; + if (BufferSize() == 0 && !Refresh()) return false; *data = buffer_; - *size = buffer_size_; + *size = BufferSize(); return true; } bool CodedInputStream::ReadRaw(void* buffer, int size) { - while (buffer_size_ < size) { + int current_buffer_size; + while ((current_buffer_size = BufferSize()) < size) { // Reading past end of buffer. Copy what we have, then refresh. - memcpy(buffer, buffer_, buffer_size_); - buffer = reinterpret_cast<uint8*>(buffer) + buffer_size_; - size -= buffer_size_; - Advance(buffer_size_); + memcpy(buffer, buffer_, current_buffer_size); + buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size; + size -= current_buffer_size; + Advance(current_buffer_size); if (!Refresh()) return false; } @@ -261,27 +215,25 @@ bool CodedInputStream::ReadRaw(void* buffer, int size) { bool CodedInputStream::ReadString(string* buffer, int size) { if (size < 0) return false; // security: size is often user-supplied + return InternalReadStringInline(buffer, size); +} +bool CodedInputStream::ReadStringFallback(string* buffer, int size) { if (!buffer->empty()) { buffer->clear(); } - if (size < buffer_size_) { - STLStringResizeUninitialized(buffer, size); - memcpy((uint8*)buffer->data(), buffer_, size); - Advance(size); - return true; - } - - while (buffer_size_ < size) { + int current_buffer_size; + while ((current_buffer_size = BufferSize()) < size) { // Some STL implementations "helpfully" crash on buffer->append(NULL, 0). - if (buffer_size_ != 0) { + if (current_buffer_size != 0) { // Note: string1.append(string2) is O(string2.size()) (as opposed to // O(string1.size() + string2.size()), which would be bad). - buffer->append(reinterpret_cast<const char*>(buffer_), buffer_size_); + buffer->append(reinterpret_cast<const char*>(buffer_), + current_buffer_size); } - size -= buffer_size_; - Advance(buffer_size_); + size -= current_buffer_size; + Advance(current_buffer_size); if (!Refresh()) return false; } @@ -292,11 +244,11 @@ bool CodedInputStream::ReadString(string* buffer, int size) { } -bool CodedInputStream::ReadLittleEndian32(uint32* value) { +bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) { uint8 bytes[sizeof(*value)]; const uint8* ptr; - if (buffer_size_ >= sizeof(*value)) { + if (BufferSize() >= sizeof(*value)) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -305,19 +257,15 @@ bool CodedInputStream::ReadLittleEndian32(uint32* value) { if (!ReadRaw(bytes, sizeof(*value))) return false; ptr = bytes; } - - *value = (static_cast<uint32>(ptr[0]) ) | - (static_cast<uint32>(ptr[1]) << 8) | - (static_cast<uint32>(ptr[2]) << 16) | - (static_cast<uint32>(ptr[3]) << 24); + ReadLittleEndian32FromArray(ptr, value); return true; } -bool CodedInputStream::ReadLittleEndian64(uint64* value) { +bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { uint8 bytes[sizeof(*value)]; const uint8* ptr; - if (buffer_size_ >= sizeof(*value)) { + if (BufferSize() >= sizeof(*value)) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -326,99 +274,152 @@ bool CodedInputStream::ReadLittleEndian64(uint64* value) { if (!ReadRaw(bytes, sizeof(*value))) return false; ptr = bytes; } + ReadLittleEndian64FromArray(ptr, value); + return true; +} + +namespace { + +inline const uint8* ReadVarint32FromArray( + const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this read won't cross the end, so we can skip the checks. + const uint8* ptr = buffer; + uint32 b; + uint32 result; + + b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; + b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done; + + // If the input is larger than 32 bits, we still need to read it all + // and discard the high-order bits. + for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) { + b = *(ptr++); if (!(b & 0x80)) goto done; + } + + // We have overrun the maximum size of a varint (10 bytes). Assume + // the data is corrupt. + return NULL; + + done: + *value = result; + return ptr; +} + +} // namespace - uint32 part0 = (static_cast<uint32>(ptr[0]) ) | - (static_cast<uint32>(ptr[1]) << 8) | - (static_cast<uint32>(ptr[2]) << 16) | - (static_cast<uint32>(ptr[3]) << 24); - uint32 part1 = (static_cast<uint32>(ptr[4]) ) | - (static_cast<uint32>(ptr[5]) << 8) | - (static_cast<uint32>(ptr[6]) << 16) | - (static_cast<uint32>(ptr[7]) << 24); - *value = static_cast<uint64>(part0) | - (static_cast<uint64>(part1) << 32); +bool CodedInputStream::ReadVarint32Slow(uint32* value) { + uint64 result; + // Directly invoke ReadVarint64Fallback, since we already tried to optimize + // for one-byte varints. + if (!ReadVarint64Fallback(&result)) return false; + *value = (uint32)result; return true; } bool CodedInputStream::ReadVarint32Fallback(uint32* value) { - if (buffer_size_ >= kMaxVarintBytes || + if (BufferSize() >= kMaxVarintBytes || // Optimization: If the varint ends at exactly the end of the buffer, // we can detect that and still use the fast path. - (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this read won't cross the end, so we can skip the checks. - const uint8* ptr = buffer_; - uint32 b; - uint32 result; - - b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done; - - // If the input is larger than 32 bits, we still need to read it all - // and discard the high-order bits. - for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) { - b = *(ptr++); if (!(b & 0x80)) goto done; - } - - // We have overrun the maximum size of a varint (10 bytes). Assume - // the data is corrupt. - return false; - - done: - Advance(ptr - buffer_); - *value = result; + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + const uint8* end = ReadVarint32FromArray(buffer_, value); + if (end == NULL) return false; + buffer_ = end; return true; - } else { - // Optimization: If we're at a limit, detect that quickly. (This is - // common when reading tags.) - while (buffer_size_ == 0) { - // Detect cases where we definitely hit a byte limit without calling - // Refresh(). - if (// If we hit a limit, buffer_size_after_limit_ will be non-zero. - buffer_size_after_limit_ > 0 && - // Make sure that the limit we hit is not total_bytes_limit_, since - // in that case we still need to call Refresh() so that it prints an - // error. - total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) { - // We hit a byte limit. - legitimate_message_end_ = true; - return false; - } + // Really slow case: we will incur the cost of an extra function call here, + // but moving this out of line reduces the size of this function, which + // improves the common case. In micro benchmarks, this is worth about 10-15% + return ReadVarint32Slow(value); + } +} - // Call refresh. - if (!Refresh()) { - // Refresh failed. Make sure that it failed due to EOF, not because - // we hit total_bytes_limit_, which, unlike normal limits, is not a - // valid place to end a message. - int current_position = total_bytes_read_ - buffer_size_after_limit_; - if (current_position >= total_bytes_limit_) { - // Hit total_bytes_limit_. But if we also hit the normal limit, - // we're still OK. - legitimate_message_end_ = current_limit_ == total_bytes_limit_; - } else { - legitimate_message_end_ = true; - } - return false; +uint32 CodedInputStream::ReadTagSlow() { + if (buffer_ == buffer_end_) { + // Call refresh. + if (!Refresh()) { + // Refresh failed. Make sure that it failed due to EOF, not because + // we hit total_bytes_limit_, which, unlike normal limits, is not a + // valid place to end a message. + int current_position = total_bytes_read_ - buffer_size_after_limit_; + if (current_position >= total_bytes_limit_) { + // Hit total_bytes_limit_. But if we also hit the normal limit, + // we're still OK. + legitimate_message_end_ = current_limit_ == total_bytes_limit_; + } else { + legitimate_message_end_ = true; } + return 0; } + } - // Slow path: Just do a 64-bit read. - uint64 result; - if (!ReadVarint64(&result)) return false; - *value = (uint32)result; - return true; + // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags + // again, since we have now refreshed the buffer. + uint64 result; + if (!ReadVarint64(&result)) return 0; + return static_cast<uint32>(result); +} + +uint32 CodedInputStream::ReadTagFallback() { + if (BufferSize() >= kMaxVarintBytes || + // Optimization: If the varint ends at exactly the end of the buffer, + // we can detect that and still use the fast path. + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { + uint32 tag; + const uint8* end = ReadVarint32FromArray(buffer_, &tag); + if (end == NULL) { + return 0; + } + buffer_ = end; + return tag; + } else { + // We are commonly at a limit when attempting to read tags. Try to quickly + // detect this case without making another function call. + if (buffer_ == buffer_end_ && buffer_size_after_limit_ > 0 && + // Make sure that the limit we hit is not total_bytes_limit_, since + // in that case we still need to call Refresh() so that it prints an + // error. + total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) { + // We hit a byte limit. + legitimate_message_end_ = true; + return 0; + } + return ReadTagSlow(); } } -bool CodedInputStream::ReadVarint64(uint64* value) { - if (buffer_size_ >= kMaxVarintBytes || +bool CodedInputStream::ReadVarint64Slow(uint64* value) { + // Slow path: This read might cross the end of the buffer, so we + // need to check and refresh the buffer if and when it does. + + uint64 result = 0; + int count = 0; + uint32 b; + + do { + if (count == kMaxVarintBytes) return false; + while (buffer_ == buffer_end_) { + if (!Refresh()) return false; + } + b = *buffer_; + result |= static_cast<uint64>(b & 0x7F) << (7 * count); + Advance(1); + ++count; + } while (b & 0x80); + + *value = result; + return true; +} + +bool CodedInputStream::ReadVarint64Fallback(uint64* value) { + if (BufferSize() >= kMaxVarintBytes || // Optimization: If the varint ends at exactly the end of the buffer, // we can detect that and still use the fast path. - (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) { + (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { // Fast path: We have enough bytes left in the buffer to guarantee that // this read won't cross the end, so we can skip the checks. @@ -442,7 +443,7 @@ bool CodedInputStream::ReadVarint64(uint64* value) { // We have overrun the maximum size of a varint (10 bytes). The data // must be corrupt. - return false; + return NULL; done: Advance(ptr - buffer_); @@ -450,33 +451,13 @@ bool CodedInputStream::ReadVarint64(uint64* value) { (static_cast<uint64>(part1) << 28) | (static_cast<uint64>(part2) << 56); return true; - } else { - // Slow path: This read might cross the end of the buffer, so we - // need to check and refresh the buffer if and when it does. - - uint64 result = 0; - int count = 0; - uint32 b; - - do { - if (count == kMaxVarintBytes) return false; - while (buffer_size_ == 0) { - if (!Refresh()) return false; - } - b = *buffer_; - result |= static_cast<uint64>(b & 0x7F) << (7 * count); - Advance(1); - ++count; - } while(b & 0x80); - - *value = result; - return true; + return ReadVarint64Slow(value); } } bool CodedInputStream::Refresh() { - GOOGLE_DCHECK_EQ(buffer_size_, 0); + GOOGLE_DCHECK_EQ(0, BufferSize()); if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 || total_bytes_read_ == current_limit_) { @@ -507,25 +488,27 @@ bool CodedInputStream::Refresh() { } const void* void_buffer; - if (input_->Next(&void_buffer, &buffer_size_)) { + int buffer_size; + if (input_->Next(&void_buffer, &buffer_size)) { buffer_ = reinterpret_cast<const uint8*>(void_buffer); - GOOGLE_CHECK_GE(buffer_size_, 0); + buffer_end_ = buffer_ + buffer_size; + GOOGLE_CHECK_GE(buffer_size, 0); - if (total_bytes_read_ <= INT_MAX - buffer_size_) { - total_bytes_read_ += buffer_size_; + if (total_bytes_read_ <= INT_MAX - buffer_size) { + total_bytes_read_ += buffer_size; } else { - // Overflow. Reset buffer_size_ to not include the bytes beyond INT_MAX. + // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX. // We can't get that far anyway, because total_bytes_limit_ is guaranteed // to be less than it. We need to keep track of the number of bytes // we discarded, though, so that we can call input_->BackUp() to back // up over them on destruction. // The following line is equivalent to: - // overflow_bytes_ = total_bytes_read_ + buffer_size_ - INT_MAX; + // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX; // except that it avoids overflows. Signed integer overflow has // undefined results according to the C standard. - overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size_); - buffer_size_ -= overflow_bytes_; + overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size); + buffer_end_ -= overflow_bytes_; total_bytes_read_ = INT_MAX; } @@ -533,7 +516,7 @@ bool CodedInputStream::Refresh() { return true; } else { buffer_ = NULL; - buffer_size_ = 0; + buffer_end_ = NULL; return false; } } diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index fa023f3..dcbb0d4 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -114,10 +114,15 @@ #include <sys/param.h> #endif // !_MSC_VER #include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/common.h> // for GOOGLE_PREDICT_TRUE macro namespace google { namespace protobuf { + +class DescriptorPool; +class MessageFactory; + namespace io { // Defined in this file. @@ -166,6 +171,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // types of data not covered by the CodedInputStream interface. bool GetDirectBufferPointer(const void** data, int* size); + // Like GetDirectBufferPointer, but this method is inlined, and does not + // attempt to Refresh() if the buffer is currently empty. + inline void GetDirectBufferPointerInline(const void** data, + int* size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + // Read raw bytes, copying them into the given buffer. bool ReadRaw(void* buffer, int size); @@ -177,6 +187,10 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // could claim that a string is going to be MAX_INT bytes long in order to // crash the server because it can't allocate this much space at once. bool ReadString(string* buffer, int size); + // Like the above, with inlined optimizations. This should only be used + // by the protobuf implementation. + inline bool InternalReadStringInline(string* buffer, + int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; // Read a 32-bit little-endian integer. @@ -184,6 +198,15 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Read a 64-bit little-endian integer. bool ReadLittleEndian64(uint64* value); + // These methods read from an externally provided buffer. The caller is + // responsible for ensuring that the buffer has sufficient space. + // Read a 32-bit little-endian integer. + static const uint8* ReadLittleEndian32FromArray(const uint8* buffer, + uint32* value); + // Read a 64-bit little-endian integer. + static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, + uint64* value); + // Read an unsigned integer with Varint encoding, truncating to 32 bits. // Reading a 32-bit value is equivalent to reading a 64-bit one and casting // it to uint32, but may be more efficient. @@ -208,6 +231,17 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // when given a constant parameter, but GCC doesn't want to inline by default. bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + // Like above, except this reads from the specified buffer. The caller is + // responsible for ensuring that the buffer is large enough to read a varint + // of the expected size. For best performance, use a compile-time constant as + // the expected tag parameter. + // + // Returns a pointer beyond the expected tag if it was found, or NULL if it + // was not. + static const uint8* ExpectTagFromArray( + const uint8* buffer, + uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + // Usually returns true if no more bytes can be read. Always returns false // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent // call to LastTagWas() will act as if ReadTag() had been called and returned @@ -318,12 +352,90 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Decrements the recursion depth. void DecrementRecursionDepth(); + // Extension Registry ---------------------------------------------- + // ADVANCED USAGE: 99.9% of people can ignore this section. + // + // By default, when parsing extensions, the parser looks for extension + // definitions in the pool which owns the outer message's Descriptor. + // However, you may call SetExtensionRegistry() to provide an alternative + // pool instead. This makes it possible, for example, to parse a message + // using a generated class, but represent some extensions using + // DynamicMessage. + + // Set the pool used to look up extensions. Most users do not need to call + // this as the correct pool will be chosen automatically. + // + // WARNING: It is very easy to misuse this. Carefully read the requirements + // below. Do not use this unless you are sure you need it. Almost no one + // does. + // + // Let's say you are parsing a message into message object m, and you want + // to take advantage of SetExtensionRegistry(). You must follow these + // requirements: + // + // The given DescriptorPool must contain m->GetDescriptor(). It is not + // sufficient for it to simply contain a descriptor that has the same name + // and content -- it must be the *exact object*. In other words: + // assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) == + // m->GetDescriptor()); + // There are two ways to satisfy this requirement: + // 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless + // because this is the pool that would be used anyway if you didn't call + // SetExtensionRegistry() at all. + // 2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an + // "underlay". Read the documentation for DescriptorPool for more + // information about underlays. + // + // You must also provide a MessageFactory. This factory will be used to + // construct Message objects representing extensions. The factory's + // GetPrototype() MUST return non-NULL for any Descriptor which can be found + // through the provided pool. + // + // If the provided factory might return instances of protocol-compiler- + // generated (i.e. compiled-in) types, or if the outer message object m is + // a generated type, then the given factory MUST have this property: If + // GetPrototype() is given a Descriptor which resides in + // DescriptorPool::generated_pool(), the factory MUST return the same + // prototype which MessageFactory::generated_factory() would return. That + // is, given a descriptor for a generated type, the factory must return an + // instance of the generated class (NOT DynamicMessage). However, when + // given a descriptor for a type that is NOT in generated_pool, the factory + // is free to return any implementation. + // + // The reason for this requirement is that generated sub-objects may be + // accessed via the standard (non-reflection) extension accessor methods, + // and these methods will down-cast the object to the generated class type. + // If the object is not actually of that type, the results would be undefined. + // On the other hand, if an extension is not compiled in, then there is no + // way the code could end up accessing it via the standard accessors -- the + // only way to access the extension is via reflection. When using reflection, + // DynamicMessage and generated messages are indistinguishable, so it's fine + // if these objects are represented using DynamicMessage. + // + // Using DynamicMessageFactory on which you have called + // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the + // above requirement. + // + // If either pool or factory is NULL, both must be NULL. + // + // Note that this feature is ignored when parsing "lite" messages as they do + // not have descriptors. + void SetExtensionRegistry(DescriptorPool* pool, MessageFactory* factory); + + // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool + // has been provided. + const DescriptorPool* GetExtensionPool(); + + // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no + // factory has been provided. + MessageFactory* GetExtensionFactory(); + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); ZeroCopyInputStream* input_; const uint8* buffer_; - int buffer_size_; // size of current buffer + const uint8* buffer_end_; // pointer to the end of the buffer. int total_bytes_read_; // total bytes read from input_, including // the current buffer @@ -334,7 +446,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // LastTagWas() stuff. uint32 last_tag_; // result of last ReadTag(). - // This is set true by ReadVarint32Fallback() if it is called when exactly + // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly // at EOF, or by ExpectAtEnd() when it returns true. This happens when we // reach the end of a message and attempt to read another tag. bool legitimate_message_end_; @@ -365,6 +477,12 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Recursion depth limit, set by SetRecursionLimit(). int recursion_limit_; + // See SetExtensionRegistry(). + const DescriptorPool* extension_pool_; + MessageFactory* extension_factory_; + + // Private member functions. + // Advance the buffer by a given number of bytes. void Advance(int amount); @@ -379,10 +497,36 @@ class LIBPROTOBUF_EXPORT CodedInputStream { void PrintTotalBytesLimitError(); // Called when the buffer runs out to request more data. Implies an - // Advance(buffer_size_). + // Advance(BufferSize()). bool Refresh(); + // When parsing varints, we optimize for the common case of small values, and + // then optimize for the case when the varint fits within the current buffer + // piece. The Fallback method is used when we can't use the one-byte + // optimization. The Slow method is yet another fallback when the buffer is + // not large enough. Making the slow path out-of-line speeds up the common + // case by 10-15%. The slow path is fairly uncommon: it only triggers when a + // message crosses multiple buffers. bool ReadVarint32Fallback(uint32* value); + bool ReadVarint64Fallback(uint64* value); + bool ReadVarint32Slow(uint32* value); + bool ReadVarint64Slow(uint64* value); + bool ReadLittleEndian32Fallback(uint32* value); + bool ReadLittleEndian64Fallback(uint64* value); + // Fallback/slow methods for reading tags. These do not update last_tag_, + // but will set legitimate_message_end_ if we are at the end of the input + // stream. + uint32 ReadTagFallback(); + uint32 ReadTagSlow(); + bool ReadStringFallback(string* buffer, int size); + + // Return the size of the buffer. + int BufferSize() const; + + static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB + + static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB + static const int kDefaultRecursionLimit = 64; }; // Class which encodes and writes binary data which is composed of varint- @@ -568,7 +712,7 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { // methods optimize for that case. inline bool CodedInputStream::ReadVarint32(uint32* value) { - if (buffer_size_ != 0 && *buffer_ < 0x80) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { *value = *buffer_; Advance(1); return true; @@ -577,20 +721,93 @@ inline bool CodedInputStream::ReadVarint32(uint32* value) { } } +inline bool CodedInputStream::ReadVarint64(uint64* value) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { + *value = *buffer_; + Advance(1); + return true; + } else { + return ReadVarint64Fallback(value); + } +} + +// static +inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( + const uint8* buffer, + uint32* value) { +#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + *value = (static_cast<uint32>(buffer[0]) ) | + (static_cast<uint32>(buffer[1]) << 8) | + (static_cast<uint32>(buffer[2]) << 16) | + (static_cast<uint32>(buffer[3]) << 24); + return buffer + sizeof(*value); +#endif +} +// static +inline const uint8* CodedInputStream::ReadLittleEndian64FromArray( + const uint8* buffer, + uint64* value) { +#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + uint32 part0 = (static_cast<uint32>(buffer[0]) ) | + (static_cast<uint32>(buffer[1]) << 8) | + (static_cast<uint32>(buffer[2]) << 16) | + (static_cast<uint32>(buffer[3]) << 24); + uint32 part1 = (static_cast<uint32>(buffer[4]) ) | + (static_cast<uint32>(buffer[5]) << 8) | + (static_cast<uint32>(buffer[6]) << 16) | + (static_cast<uint32>(buffer[7]) << 24); + *value = static_cast<uint64>(part0) | + (static_cast<uint64>(part1) << 32); + return buffer + sizeof(*value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian32(uint32* value) { +#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN + if (GOOGLE_PREDICT_TRUE(BufferSize() >= sizeof(*value))) { + memcpy(value, buffer_, sizeof(*value)); + Advance(sizeof(*value)); + return true; + } else { + return ReadLittleEndian32Fallback(value); + } +#else + return ReadLittleEndian32Fallback(value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian64(uint64* value) { +#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN + if (GOOGLE_PREDICT_TRUE(BufferSize() >= sizeof(*value))) { + memcpy(value, buffer_, sizeof(*value)); + Advance(sizeof(*value)); + return true; + } else { + return ReadLittleEndian64Fallback(value); + } +#else + return ReadLittleEndian64Fallback(value); +#endif +} + inline uint32 CodedInputStream::ReadTag() { - if (buffer_size_ != 0 && buffer_[0] < 0x80) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] < 0x80) { last_tag_ = buffer_[0]; Advance(1); return last_tag_; - } else if (buffer_size_ >= 2 && buffer_[1] < 0x80) { - last_tag_ = (buffer_[0] & 0x7f) + (buffer_[1] << 7); - Advance(2); - return last_tag_; - } else if (ReadVarint32Fallback(&last_tag_)) { - return last_tag_; } else { - last_tag_ = 0; - return 0; + last_tag_ = ReadTagFallback(); + return last_tag_; } } @@ -604,14 +821,14 @@ inline bool CodedInputStream::ConsumedEntireMessage() { inline bool CodedInputStream::ExpectTag(uint32 expected) { if (expected < (1 << 7)) { - if (buffer_size_ != 0 && buffer_[0] == expected) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) { Advance(1); return true; } else { return false; } } else if (expected < (1 << 14)) { - if (buffer_size_ >= 2 && + if (GOOGLE_PREDICT_TRUE(BufferSize() >= 2) && buffer_[0] == static_cast<uint8>(expected | 0x80) && buffer_[1] == static_cast<uint8>(expected >> 7)) { Advance(2); @@ -625,11 +842,32 @@ inline bool CodedInputStream::ExpectTag(uint32 expected) { } } +inline const uint8* CodedInputStream::ExpectTagFromArray( + const uint8* buffer, uint32 expected) { + if (expected < (1 << 7)) { + if (buffer[0] == expected) { + return buffer + 1; + } + } else if (expected < (1 << 14)) { + if (buffer[0] == static_cast<uint8>(expected | 0x80) && + buffer[1] == static_cast<uint8>(expected >> 7)) { + return buffer + 2; + } + } + return NULL; +} + +inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, + int* size) { + *data = buffer_; + *size = buffer_end_ - buffer_; +} + inline bool CodedInputStream::ExpectAtEnd() { // If we are at a limit we know no more bytes can be read. Otherwise, it's // hard to say without calling Refresh(), and we'd rather not do that. - if (buffer_size_ == 0 && buffer_size_after_limit_ != 0) { + if (buffer_ == buffer_end_ && buffer_size_after_limit_ != 0) { last_tag_ = 0; // Pretend we called ReadTag()... legitimate_message_end_ = true; // ... and it hit EOF. return true; @@ -677,11 +915,11 @@ inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, uint8* target) { -#if !defined(PROTOBUF_TEST_NOT_LITTLE_ENDIAN) && \ +#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN memcpy(target, &value, sizeof(value)); #else - target[0] = static_cast<uint8>(value ); + target[0] = static_cast<uint8>(value); target[1] = static_cast<uint8>(value >> 8); target[2] = static_cast<uint8>(value >> 16); target[3] = static_cast<uint8>(value >> 24); @@ -691,18 +929,18 @@ inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value, uint8* target) { -#if !defined(PROTOBUF_TEST_NOT_LITTLE_ENDIAN) && \ +#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \ defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN memcpy(target, &value, sizeof(value)); #else uint32 part0 = static_cast<uint32>(value); uint32 part1 = static_cast<uint32>(value >> 32); - target[0] = static_cast<uint8>(part0 ); + target[0] = static_cast<uint8>(part0); target[1] = static_cast<uint8>(part0 >> 8); target[2] = static_cast<uint8>(part0 >> 16); target[3] = static_cast<uint8>(part0 >> 24); - target[4] = static_cast<uint8>(part1 ); + target[4] = static_cast<uint8>(part1); target[5] = static_cast<uint8>(part1 >> 8); target[6] = static_cast<uint8>(part1 >> 16); target[7] = static_cast<uint8>(part1 >> 24); @@ -759,7 +997,6 @@ inline int CodedOutputStream::ByteCount() const { inline void CodedInputStream::Advance(int amount) { buffer_ += amount; - buffer_size_ -= amount; } inline void CodedOutputStream::Advance(int amount) { @@ -780,6 +1017,72 @@ inline void CodedInputStream::DecrementRecursionDepth() { if (recursion_depth_ > 0) --recursion_depth_; } +inline void CodedInputStream::SetExtensionRegistry(DescriptorPool* pool, + MessageFactory* factory) { + extension_pool_ = pool; + extension_factory_ = factory; +} + +inline const DescriptorPool* CodedInputStream::GetExtensionPool() { + return extension_pool_; +} + +inline MessageFactory* CodedInputStream::GetExtensionFactory() { + return extension_factory_; +} + +inline int CodedInputStream::BufferSize() const { + return buffer_end_ - buffer_; +} + +inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) + : input_(input), + buffer_(NULL), + buffer_end_(NULL), + total_bytes_read_(0), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(INT_MAX), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), + recursion_depth_(0), + recursion_limit_(kDefaultRecursionLimit), + extension_pool_(NULL), + extension_factory_(NULL) { + // Eagerly Refresh() so buffer space is immediately available. + Refresh(); +} + +inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) + : input_(NULL), + buffer_(buffer), + buffer_end_(buffer + size), + total_bytes_read_(size), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(size), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), + recursion_depth_(0), + recursion_limit_(kDefaultRecursionLimit), + extension_pool_(NULL), + extension_factory_(NULL) { + // Note that setting current_limit_ == size is important to prevent some + // code paths from trying to access input_ and segfaulting. +} + +inline CodedInputStream::~CodedInputStream() { + if (input_ != NULL) { + BackUpInputToCurrentPosition(); + } +} + } // namespace io } // namespace protobuf diff --git a/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java b/src/google/protobuf/io/coded_stream_inl.h index 0c43e54..e9799d4 100644 --- a/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java +++ b/src/google/protobuf/io/coded_stream_inl.h @@ -28,40 +28,37 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -package com.google.protobuf.micro; +// Author: jasonh@google.com (Jason Hsueh) +// +// Implements methods of coded_stream.h that need to be inlined for performance +// reasons, but should not be defined in a public header. -/** - * A surogate for a String with a UTF8 representation. - * - * @author wink@google.com Wink Saville - */ -public final class StringUtf8Micro { - private String string; - private byte[] bytes; +#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ +#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ - public StringUtf8Micro(String string) { - setString(string); - } +#include <google/protobuf/io/coded_stream.h> +#include <string> +#include <google/protobuf/stubs/stl_util-inl.h> - public static final StringUtf8Micro EMPTY = new StringUtf8Micro(""); +namespace google { +namespace protobuf { +namespace io { - public String getString() { - return string; - } +inline bool CodedInputStream::InternalReadStringInline(string* buffer, + int size) { + if (size < 0) return false; // security: size is often user-supplied - public void setString(String string) { - this.string = string; - bytes = null; + if (BufferSize() >= size) { + STLStringResizeUninitialized(buffer, size); + memcpy(string_as_array(buffer), buffer_, size); + Advance(size); + return true; } - public byte [] getBytes() { - if (bytes == null) { - try { - bytes = string.getBytes("UTF-8"); - } catch (java.io.UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported."); - } - } - return bytes; - } + return ReadStringFallback(buffer, size); } + +} // namespace io +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__ diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc index e165fb9..7d29833 100644 --- a/src/google/protobuf/io/coded_stream_unittest.cc +++ b/src/google/protobuf/io/coded_stream_unittest.cc @@ -242,6 +242,24 @@ TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) { } } +TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) { + memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); + + const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value); + + // If the expectation succeeds, it should return a pointer past the tag. + if (kVarintCases_case.size <= 2) { + EXPECT_TRUE(NULL == + CodedInputStream::ExpectTagFromArray(buffer_, + expected_value + 1)); + EXPECT_TRUE(buffer_ + kVarintCases_case.size == + CodedInputStream::ExpectTagFromArray(buffer_, expected_value)); + } else { + EXPECT_TRUE(NULL == + CodedInputStream::ExpectTagFromArray(buffer_, expected_value)); + } +} + TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) { memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); @@ -529,10 +547,32 @@ TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) { EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64))); } +// Tests using the static methods to read fixed-size values from raw arrays. + +TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) { + memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes)); + + uint32 value; + const uint8* end = CodedInputStream::ReadLittleEndian32FromArray( + buffer_, &value); + EXPECT_EQ(kFixed32Cases_case.value, value); + EXPECT_TRUE(end == buffer_ + sizeof(value)); +} + +TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) { + memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes)); + + uint64 value; + const uint8* end = CodedInputStream::ReadLittleEndian64FromArray( + buffer_, &value); + EXPECT_EQ(kFixed64Cases_case.value, value); + EXPECT_TRUE(end == buffer_ + sizeof(value)); +} + // ------------------------------------------------------------------- // Raw reads and writes -const char kRawBytes[] = "Some bytes which will be writted and read raw."; +const char kRawBytes[] = "Some bytes which will be written and read raw."; TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) { memcpy(buffer_, kRawBytes, sizeof(kRawBytes)); @@ -593,6 +633,22 @@ TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) { } } +TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) { + // Same test as above, except directly use a buffer. This used to cause + // crashes while the above did not. + uint8 buffer[8]; + CodedInputStream coded_input(buffer, 8); + string str; + EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); +} + +TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) { + scoped_array<uint8> buffer(new uint8[8]); + CodedInputStream coded_input(buffer.get(), 8); + string str; + EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); +} + // ------------------------------------------------------------------- // Skip @@ -652,6 +708,36 @@ TEST_F(CodedStreamTest, GetDirectBufferPointerInput) { EXPECT_EQ(8, size); } +TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) { + ArrayInputStream input(buffer_, sizeof(buffer_), 8); + CodedInputStream coded_input(&input); + + const void* ptr; + int size; + + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Peeking again should return the same pointer. + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_, ptr); + EXPECT_EQ(8, size); + + // Skip forward in the same buffer then peek again. + EXPECT_TRUE(coded_input.Skip(3)); + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_ + 3, ptr); + EXPECT_EQ(5, size); + + // Skip to end of buffer and peek -- should return false and provide an empty + // buffer. It does not try to Refresh(). + EXPECT_TRUE(coded_input.Skip(5)); + coded_input.GetDirectBufferPointerInline(&ptr, &size); + EXPECT_EQ(buffer_ + 8, ptr); + EXPECT_EQ(0, size); +} + TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) { ArrayOutputStream output(buffer_, sizeof(buffer_), 8); CodedOutputStream coded_output(&output); diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc index 937d777..c7d3074 100644 --- a/src/google/protobuf/io/printer.cc +++ b/src/google/protobuf/io/printer.cc @@ -65,10 +65,10 @@ void Printer::Print(const map<string, string>& variables, const char* text) { if (text[i] == '\n') { // Saw newline. If there is more text, we may need to insert an indent // here. So, write what we have so far, including the '\n'. - Write(text + pos, i - pos + 1); + WriteRaw(text + pos, i - pos + 1); pos = i + 1; - // Setting this true will cause the next Write() to insert an indent + // Setting this true will cause the next WriteRaw() to insert an indent // first. at_start_of_line_ = true; @@ -76,7 +76,7 @@ void Printer::Print(const map<string, string>& variables, const char* text) { // Saw the start of a variable name. // Write what we have so far. - Write(text + pos, i - pos); + WriteRaw(text + pos, i - pos); pos = i + 1; // Find closing delimiter. @@ -90,14 +90,14 @@ void Printer::Print(const map<string, string>& variables, const char* text) { string varname(text + pos, endpos - pos); if (varname.empty()) { // Two delimiters in a row reduce to a literal delimiter character. - Write(&variable_delimiter_, 1); + WriteRaw(&variable_delimiter_, 1); } else { // Replace with the variable's value. map<string, string>::const_iterator iter = variables.find(varname); if (iter == variables.end()) { GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname; } else { - Write(iter->second.data(), iter->second.size()); + WriteRaw(iter->second.data(), iter->second.size()); } } @@ -108,7 +108,7 @@ void Printer::Print(const map<string, string>& variables, const char* text) { } // Write the rest. - Write(text + pos, size - pos); + WriteRaw(text + pos, size - pos); } void Printer::Print(const char* text) { @@ -145,14 +145,23 @@ void Printer::Outdent() { indent_.resize(indent_.size() - 2); } -void Printer::Write(const char* data, int size) { +void Printer::PrintRaw(const string& data) { + WriteRaw(data.data(), data.size()); +} + +void Printer::PrintRaw(const char* data) { + if (failed_) return; + WriteRaw(data, strlen(data)); +} + +void Printer::WriteRaw(const char* data, int size) { if (failed_) return; if (size == 0) return; if (at_start_of_line_) { // Insert an indent. at_start_of_line_ = false; - Write(indent_.data(), indent_.size()); + WriteRaw(indent_.data(), indent_.size()); if (failed_) return; } diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h index b7c4cf3..de08538 100644 --- a/src/google/protobuf/io/printer.h +++ b/src/google/protobuf/io/printer.h @@ -59,8 +59,8 @@ class ZeroCopyOutputStream; // zero_copy_stream.h // The above writes "My name is Bob." to the output stream. // // Printer aggressively enforces correct usage, crashing (with assert failures) -// in the case of undefined variables. This helps greatly in debugging code -// which uses it. This class is not intended to be used by production servers. +// in the case of undefined variables in debug builds. This helps greatly in +// debugging code which uses it. class LIBPROTOBUF_EXPORT Printer { public: // Create a printer that writes text to the given output stream. Use the @@ -94,15 +94,24 @@ class LIBPROTOBUF_EXPORT Printer { // level is zero. void Outdent(); + // Write a string to the output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const string& data); + + // Write a zero-delimited string to output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const char* data); + + // Write some bytes to the output buffer. + // This method does not look for newlines to add indentation. + void WriteRaw(const char* data, int size); + // True if any write to the underlying stream failed. (We don't just // crash in this case because this is an I/O failure, not a programming // error.) bool failed() const { return failed_; } private: - // Write some text to the output buffer. - void Write(const char* data, int size); - const char variable_delimiter_; ZeroCopyOutputStream* const output_; diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc index 69c7ee3..580a53d 100644 --- a/src/google/protobuf/io/printer_unittest.cc +++ b/src/google/protobuf/io/printer_unittest.cc @@ -76,10 +76,38 @@ TEST(Printer, BasicPrinting) { buffer[output.ByteCount()] = '\0'; - EXPECT_STREQ(buffer, - "Hello World! This is the same line.\n" - "But this is a new one.\n" - "And this is another one."); + EXPECT_STREQ("Hello World! This is the same line.\n" + "But this is a new one.\n" + "And this is another one.", + buffer); + } +} + +TEST(Printer, WriteRaw) { + char buffer[8192]; + + for (int block_size = 1; block_size < 512; block_size *= 2) { + ArrayOutputStream output(buffer, sizeof(buffer), block_size); + + { + string string_obj = "From an object\n"; + Printer printer(&output, '$'); + printer.WriteRaw("Hello World!", 12); + printer.PrintRaw(" This is the same line.\n"); + printer.PrintRaw("But this is a new one.\nAnd this is another one."); + printer.WriteRaw("\n", 1); + printer.PrintRaw(string_obj); + EXPECT_FALSE(printer.failed()); + } + + buffer[output.ByteCount()] = '\0'; + + EXPECT_STREQ("Hello World! This is the same line.\n" + "But this is a new one.\n" + "And this is another one." + "\n" + "From an object\n", + buffer); } } @@ -98,6 +126,7 @@ TEST(Printer, VariableSubstitution) { vars["abcdefg"] = "1234"; printer.Print(vars, "Hello $foo$!\nbar = $bar$\n"); + printer.PrintRaw("RawBit\n"); printer.Print(vars, "$abcdefg$\nA literal dollar sign: $$"); vars["foo"] = "blah"; @@ -108,12 +137,13 @@ TEST(Printer, VariableSubstitution) { buffer[output.ByteCount()] = '\0'; - EXPECT_STREQ(buffer, - "Hello World!\n" - "bar = $foo$\n" - "1234\n" - "A literal dollar sign: $\n" - "Now foo = blah."); + EXPECT_STREQ("Hello World!\n" + "bar = $foo$\n" + "RawBit\n" + "1234\n" + "A literal dollar sign: $\n" + "Now foo = blah.", + buffer); } } @@ -125,15 +155,17 @@ TEST(Printer, InlineVariableSubstitution) { { Printer printer(&output, '$'); printer.Print("Hello $foo$!\n", "foo", "World"); + printer.PrintRaw("RawBit\n"); printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two"); EXPECT_FALSE(printer.failed()); } buffer[output.ByteCount()] = '\0'; - EXPECT_STREQ(buffer, - "Hello World!\n" - "one two\n"); + EXPECT_STREQ("Hello World!\n" + "RawBit\n" + "one two\n", + buffer); } TEST(Printer, Indenting) { @@ -156,6 +188,8 @@ TEST(Printer, Indenting) { printer.Indent(); printer.Print(" And this is still the same line.\n" "But this is indented.\n"); + printer.PrintRaw("RawBit has indent at start\n"); + printer.PrintRaw("but not after a raw newline\n"); printer.Print(vars, "Note that a newline in a variable will break " "indenting, as we see$newline$here.\n"); printer.Indent(); @@ -169,16 +203,19 @@ TEST(Printer, Indenting) { buffer[output.ByteCount()] = '\0'; - EXPECT_STREQ(buffer, + EXPECT_STREQ( "This is not indented.\n" " This is indented\n" " And so is this\n" "But this is not. And this is still the same line.\n" " But this is indented.\n" - " Note that a newline in a variable will break indenting, as we see\n" + " RawBit has indent at start\n" + "but not after a raw newline\n" + "Note that a newline in a variable will break indenting, as we see\n" "here.\n" " And this is double-indented\n" - "Back to normal."); + "Back to normal.", + buffer); } } diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index 0bda451..38fa351 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc @@ -117,9 +117,9 @@ namespace { } CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' || - c == '\r' || c == '\v'); + c == '\r' || c == '\v' || c == '\f'); -CHARACTER_CLASS(Unprintable, c < ' ' && c != '\0'); +CHARACTER_CLASS(Unprintable, c < ' ' && c > '\0'); CHARACTER_CLASS(Digit, '0' <= c && c <= '9'); CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7'); diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h index 98386e0..d115161 100644 --- a/src/google/protobuf/io/tokenizer.h +++ b/src/google/protobuf/io/tokenizer.h @@ -63,6 +63,11 @@ class LIBPROTOBUF_EXPORT ErrorCollector { // 1 to each before printing them. virtual void AddError(int line, int column, const string& message) = 0; + // Indicates that there was a warning in the input at the given line and + // column numbers. The numbers are zero-based, so you may want to add + // 1 to each before printing them. + virtual void AddWarning(int line, int column, const string& message) { } + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); }; diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc index eac1455..358ec56 100644 --- a/src/google/protobuf/io/tokenizer_unittest.cc +++ b/src/google/protobuf/io/tokenizer_unittest.cc @@ -397,6 +397,19 @@ MultiTokenCase kMultiTokenCases[] = { { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0 }, { Tokenizer::TYPE_END , "" , 1, 3 }, }}, + + // Bytes with the high-order bit set should not be seen as control characters. + { "\300", { + { Tokenizer::TYPE_SYMBOL, "\300", 0, 0 }, + { Tokenizer::TYPE_END , "" , 0, 1 }, + }}, + + // Test all whitespace chars + { "foo\n\t\r\v\fbar", { + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11 }, + { Tokenizer::TYPE_END , "" , 1, 14 }, + }}, }; TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index 64e96cd..9fedb00 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h @@ -133,10 +133,11 @@ class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { // A ZeroCopyOutputStream which writes to a file descriptor. // -// FileInputStream is preferred over using an ofstream with OstreamOutputStream. -// The latter will introduce an extra layer of buffering, harming performance. -// Also, it's conceivable that FileInputStream could someday be enhanced -// to use zero-copy file descriptors on OSs which support them. +// FileOutputStream is preferred over using an ofstream with +// OstreamOutputStream. The latter will introduce an extra layer of buffering, +// harming performance. Also, it's conceivable that FileOutputStream could +// someday be enhanced to use zero-copy file descriptors on OSs which +// support them. class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { public: // Creates a stream that writes to the given Unix file descriptor. diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index c8f669a..8229ee6 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -403,7 +403,8 @@ TEST_F(IoTest, CompressionOptions) { string golden; File::ReadFileToStringOrDie( - TestSourceDir() + "/google/protobuf/testdata/golden_message", &golden); + TestSourceDir() + "/google/protobuf/testdata/golden_message", + &golden); GzipOutputStream::Options options; string gzip_compressed = Compress(golden, options); @@ -520,7 +521,7 @@ TEST_F(IoTest, GzipFileIo) { // these debug assertions while in scope. class MsvcDebugDisabler { public: -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER >= 1400 MsvcDebugDisabler() { old_handler_ = _set_invalid_parameter_handler(MyHandler); old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0); diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 4e5b662..91e6878 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -168,8 +168,11 @@ bool Message::SerializePartialToFileDescriptor(int file_descriptor) const { } bool Message::SerializeToOstream(ostream* output) const { - io::OstreamOutputStream zero_copy_output(output); - return SerializeToZeroCopyStream(&zero_copy_output); + { + io::OstreamOutputStream zero_copy_output(output); + if (!SerializeToZeroCopyStream(&zero_copy_output)) return false; + } + return output->good(); } bool Message::SerializePartialToOstream(ostream* output) const { @@ -227,7 +230,7 @@ GeneratedMessageFactory::GeneratedMessageFactory() {} GeneratedMessageFactory::~GeneratedMessageFactory() {} GeneratedMessageFactory* GeneratedMessageFactory::singleton() { - GoogleOnceInit(&generated_message_factory_once_init_, + ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_, &InitGeneratedMessageFactory); return generated_message_factory_; } diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 54b596d..c0062f9 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -148,6 +148,7 @@ namespace protobuf { // Defined in this file. class Message; class Reflection; +class MessageFactory; // Defined in other files. class Descriptor; // descriptor.h @@ -238,13 +239,15 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // Reflection object's SpaceUsed() method. virtual int SpaceUsed() const; - // Debugging ------------------------------------------------------- + // Debugging & Testing---------------------------------------------- // Generates a human readable form of this message, useful for debugging // and other purposes. string DebugString() const; // Like DebugString(), but with less whitespace. string ShortDebugString() const; + // Like DebugString(), but do not escape UTF-8 byte sequences. + string Utf8DebugString() const; // Convenience function useful in GDB. Prints DebugString() to stdout. void PrintDebugString() const; @@ -327,6 +330,7 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // GetReflection() wrappers. virtual Metadata GetMetadata() const = 0; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); }; @@ -453,8 +457,10 @@ class LIBPROTOBUF_EXPORT Reflection { const FieldDescriptor* field) const = 0; virtual const EnumValueDescriptor* GetEnum( const Message& message, const FieldDescriptor* field) const = 0; + // See MutableMessage() for the meaning of the "factory" parameter. virtual const Message& GetMessage(const Message& message, - const FieldDescriptor* field) const = 0; + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; // Get a string value without copying, if possible. // @@ -499,9 +505,19 @@ class LIBPROTOBUF_EXPORT Reflection { virtual void SetEnum (Message* message, const FieldDescriptor* field, const EnumValueDescriptor* value) const = 0; - // Get a mutable pointer to a field with a message type. + // Get a mutable pointer to a field with a message type. If a MessageFactory + // is provided, it will be used to construct instances of the sub-message; + // otherwise, the default factory is used. If the field is an extension that + // does not live in the same pool as the containing message's descriptor (e.g. + // it lives in an overlay pool), then a MessageFactory must be provided. + // If you have no idea what that meant, then you probably don't need to worry + // about it (don't provide a MessageFactory). WARNING: If the + // FieldDescriptor is for a compiled-in extension, then + // factory->GetPrototype(field->message_type() MUST return an instance of the + // compiled-in class for this type, NOT DynamicMessage. virtual Message* MutableMessage(Message* message, - const FieldDescriptor* field) const = 0; + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; // Repeated field getters ------------------------------------------ @@ -603,8 +619,10 @@ class LIBPROTOBUF_EXPORT Reflection { virtual void AddEnum (Message* message, const FieldDescriptor* field, const EnumValueDescriptor* value) const = 0; + // See MutableMessage() for comments on the "factory" parameter. virtual Message* AddMessage(Message* message, - const FieldDescriptor* field) const = 0; + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; // Extensions ------------------------------------------------------ diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index a53740a..7c8f37d 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -33,9 +33,8 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. - #include <google/protobuf/message_lite.h> - +#include <string> #include <google/protobuf/stubs/common.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> @@ -52,6 +51,24 @@ string MessageLite::InitializationErrorString() const { namespace { +// When serializing, we first compute the byte size, then serialize the message. +// If serialization produces a different number of bytes than expected, we +// call this function, which crashes. The problem could be due to a bug in the +// protobuf implementation but is more likely caused by concurrent modification +// of the message. This function attempts to distinguish between the two and +// provide a useful error message. +void ByteSizeConsistencyError(int byte_size_before_serialization, + int byte_size_after_serialization, + int bytes_produced_by_serialization) { + GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization) + << "Protocol message was modified concurrently during serialization."; + GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization) + << "Byte size calculation and serialization were inconsistent. This " + "may indicate a bug in protocol buffers or it may be caused by " + "concurrent modification of the message."; + GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal."; +} + string InitializationErrorMessage(const char* action, const MessageLite& message) { // Note: We want to avoid depending on strutil in the lite library, otherwise @@ -215,9 +232,29 @@ bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const { bool MessageLite::SerializePartialToCodedStream( io::CodedOutputStream* output) const { - ByteSize(); // Force size to be cached. - SerializeWithCachedSizes(output); - return !output->HadError(); + const int size = ByteSize(); // Force size to be cached. + uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size); + if (buffer != NULL) { + uint8* end = SerializeWithCachedSizesToArray(buffer); + if (end - buffer != size) { + ByteSizeConsistencyError(size, ByteSize(), end - buffer); + } + return true; + } else { + int original_byte_count = output->ByteCount(); + SerializeWithCachedSizes(output); + if (output->HadError()) { + return false; + } + int final_byte_count = output->ByteCount(); + + if (final_byte_count - original_byte_count != size) { + ByteSizeConsistencyError(size, ByteSize(), + final_byte_count - original_byte_count); + } + + return true; + } } bool MessageLite::SerializeToZeroCopyStream( @@ -243,7 +280,9 @@ bool MessageLite::AppendPartialToString(string* output) const { STLStringResizeUninitialized(output, old_size + byte_size); uint8* start = reinterpret_cast<uint8*>(string_as_array(output) + old_size); uint8* end = SerializeWithCachedSizesToArray(start); - GOOGLE_CHECK_EQ(end - start, byte_size); + if (end - start != byte_size) { + ByteSizeConsistencyError(byte_size, ByteSize(), end - start); + } return true; } @@ -265,9 +304,11 @@ bool MessageLite::SerializeToArray(void* data, int size) const { bool MessageLite::SerializePartialToArray(void* data, int size) const { int byte_size = ByteSize(); if (size < byte_size) return false; - uint8* end = - SerializeWithCachedSizesToArray(reinterpret_cast<uint8*>(data)); - GOOGLE_CHECK_EQ(end, reinterpret_cast<uint8*>(data) + byte_size); + uint8* start = reinterpret_cast<uint8*>(data); + uint8* end = SerializeWithCachedSizesToArray(start); + if (end - start != byte_size) { + ByteSizeConsistencyError(byte_size, ByteSize(), end - start); + } return true; } diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc index 46e6844..33b9e77 100644 --- a/src/google/protobuf/message_unittest.cc +++ b/src/google/protobuf/message_unittest.cc @@ -43,6 +43,7 @@ #include <unistd.h> #endif #include <sstream> +#include <fstream> #include <google/protobuf/stubs/common.h> #include <google/protobuf/io/zero_copy_stream_impl.h> @@ -77,9 +78,9 @@ TEST(MessageTest, SerializeHelpers) { string str1("foo"); string str2("bar"); - message.SerializeToString(&str1); - message.AppendToString(&str2); - message.SerializeToOstream(&stream); + EXPECT_TRUE(message.SerializeToString(&str1)); + EXPECT_TRUE(message.AppendToString(&str2)); + EXPECT_TRUE(message.SerializeToOstream(&stream)); EXPECT_EQ(str1.size() + 3, str2.size()); EXPECT_EQ("bar", str2.substr(0, 3)); @@ -95,6 +96,14 @@ TEST(MessageTest, SerializeHelpers) { } +TEST(MessageTest, SerializeToBrokenOstream) { + ofstream out; + protobuf_unittest::TestAllTypes message; + message.set_optional_int32(123); + + EXPECT_FALSE(message.SerializeToOstream(&out)); +} + TEST(MessageTest, ParseFromFileDescriptor) { string filename = TestSourceDir() + "/google/protobuf/testdata/golden_message"; diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc index 3230c04..f7beb11 100644 --- a/src/google/protobuf/repeated_field.cc +++ b/src/google/protobuf/repeated_field.cc @@ -39,6 +39,18 @@ namespace google { namespace protobuf { namespace internal { +void RepeatedPtrFieldBase::Reserve(int new_size) { + if (total_size_ >= new_size) return; + + void** old_elements = elements_; + total_size_ = max(total_size_ * 2, new_size); + elements_ = new void*[total_size_]; + memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0])); + if (old_elements != initial_space_) { + delete [] old_elements; + } +} + void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { void** swap_elements = elements_; int swap_current_size = current_size_; diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 43c9f3f..defdefe 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -51,8 +51,8 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/message_lite.h> - namespace google { + namespace protobuf { class Message; @@ -76,10 +76,11 @@ class RepeatedField { int size() const; - Element Get(int index) const; + const Element& Get(int index) const; Element* Mutable(int index); - void Set(int index, Element value); - void Add(Element value); + void Set(int index, const Element& value); + void Add(const Element& value); + Element* Add(); // Remove the last element in the array. // We don't provide a way to remove any element other than the last // because it invites inefficient use, such as O(n^2) filtering loops @@ -94,6 +95,13 @@ class RepeatedField { // array is grown, it will always be at least doubled in size. void Reserve(int new_size); + // Resize the RepeatedField to a new, smaller size. This is O(1). + void Truncate(int new_size); + + void AddAlreadyReserved(const Element& value); + Element* AddAlreadyReserved(); + int Capacity() const; + // Gets the underlying array. This pointer is possibly invalidated by // any add or remove operation. Element* mutable_data(); @@ -128,10 +136,19 @@ class RepeatedField { int total_size_; Element initial_space_[kInitialSize]; + + // Move the contents of |from| into |to|, possibly clobbering |from| in the + // process. For primitive types this is just a memcpy(), but it could be + // specialized for non-primitive types to, say, swap each element instead. + void MoveArray(Element to[], Element from[], int size); + + // Copy the elements of |from| into |to|. + void CopyArray(Element to[], const Element from[], int size); }; namespace internal { template <typename It> class RepeatedPtrIterator; +template <typename It> class RepeatedPtrOverPtrsIterator; } // namespace internal namespace internal { @@ -189,8 +206,11 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { void Reserve(int new_size); + int Capacity() const; + // Used for constructing iterators. void* const* raw_data() const; + void** raw_mutable_data() const; template <typename TypeHandler> typename TypeHandler::Type** mutable_data(); @@ -204,6 +224,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { template <typename TypeHandler> int SpaceUsedExcludingSelf() const; + // Advanced memory management -------------------------------------- // Like Add(), but if there are no cleared objects to use, returns NULL. @@ -215,7 +236,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { template <typename TypeHandler> typename TypeHandler::Type* ReleaseLast(); - int ClearedCount(); + int ClearedCount() const; template <typename TypeHandler> void AddCleared(typename TypeHandler::Type* value); template <typename TypeHandler> @@ -286,6 +307,7 @@ class StringTypeHandler : public StringTypeHandlerBase { } }; + } // namespace internal // RepeatedPtrField is like RepeatedField, but used for repeated strings or @@ -311,6 +333,8 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { // array is grown, it will always be at least doubled in size. void Reserve(int new_size); + int Capacity() const; + // Gets the underlying array. This pointer is possibly invalidated by // any add or remove operation. Element** mutable_data(); @@ -331,6 +355,12 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { iterator end(); const_iterator end() const; + // Custom STL-like iterator that iterates over and returns the underlying + // pointers to Element rather than Element itself. + typedef internal::RepeatedPtrOverPtrsIterator<Element> pointer_iterator; + pointer_iterator pointer_begin(); + pointer_iterator pointer_end(); + // Returns (an estimate of) the number of bytes used by the repeated field, // excluding sizeof(*this). int SpaceUsedExcludingSelf() const; @@ -363,7 +393,7 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { // Get the number of cleared objects that are currently being kept // around for reuse. - int ClearedCount(); + int ClearedCount() const; // Add an element to the pool of cleared objects, passing ownership to // the RepeatedPtrField. The element must be cleared prior to calling // this method. @@ -373,16 +403,16 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { // Requires: ClearedCount() > 0 Element* ReleaseCleared(); - private: + protected: + // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only + // subclass it in one place as a hack for compatibility with proto1. The + // subclass needs to know about TypeHandler in order to call protected + // methods on RepeatedPtrFieldBase. class TypeHandler; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField); - // prototype_ is used for RepeatedPtrField<Message> and - // RepeatedPtrField<MessageLite> only (see constructor). - // TODO(kenton): Can we use some template magic to avoid wasting space on - // this field when it isn't used? - const Element* prototype_; + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField); }; // implementation ==================================================== @@ -406,9 +436,25 @@ inline int RepeatedField<Element>::size() const { return current_size_; } +template <typename Element> +inline int RepeatedField<Element>::Capacity() const { + return total_size_; +} + +template<typename Element> +inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) { + GOOGLE_DCHECK_LT(size(), Capacity()); + elements_[current_size_++] = value; +} + +template<typename Element> +inline Element* RepeatedField<Element>::AddAlreadyReserved() { + GOOGLE_DCHECK_LT(size(), Capacity()); + return &elements_[current_size_++]; +} template <typename Element> -inline Element RepeatedField<Element>::Get(int index) const { +inline const Element& RepeatedField<Element>::Get(int index) const { GOOGLE_DCHECK_LT(index, size()); return elements_[index]; } @@ -420,18 +466,24 @@ inline Element* RepeatedField<Element>::Mutable(int index) { } template <typename Element> -inline void RepeatedField<Element>::Set(int index, Element value) { +inline void RepeatedField<Element>::Set(int index, const Element& value) { GOOGLE_DCHECK_LT(index, size()); elements_[index] = value; } template <typename Element> -inline void RepeatedField<Element>::Add(Element value) { +inline void RepeatedField<Element>::Add(const Element& value) { if (current_size_ == total_size_) Reserve(total_size_ + 1); elements_[current_size_++] = value; } template <typename Element> +inline Element* RepeatedField<Element>::Add() { + if (current_size_ == total_size_) Reserve(total_size_ + 1); + return &elements_[current_size_++]; +} + +template <typename Element> inline void RepeatedField<Element>::RemoveLast() { GOOGLE_DCHECK_GT(current_size_, 0); --current_size_; @@ -443,10 +495,9 @@ inline void RepeatedField<Element>::Clear() { } template <typename Element> -void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { +inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { Reserve(current_size_ + other.current_size_); - memcpy(elements_ + current_size_, other.elements_, - sizeof(Element) * other.current_size_); + CopyArray(elements_ + current_size_, other.elements_, other.current_size_); current_size_ += other.current_size_; } @@ -469,17 +520,17 @@ void RepeatedField<Element>::Swap(RepeatedField* other) { // We may not be using initial_space_ but it's not worth checking. Just // copy it anyway. Element swap_initial_space[kInitialSize]; - memcpy(swap_initial_space, initial_space_, sizeof(initial_space_)); + MoveArray(swap_initial_space, initial_space_, kInitialSize); elements_ = other->elements_; current_size_ = other->current_size_; total_size_ = other->total_size_; - memcpy(initial_space_, other->initial_space_, sizeof(initial_space_)); + MoveArray(initial_space_, other->initial_space_, kInitialSize); other->elements_ = swap_elements; other->current_size_ = swap_current_size; other->total_size_ = swap_total_size; - memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space)); + MoveArray(other->initial_space_, swap_initial_space, kInitialSize); if (elements_ == other->initial_space_) { elements_ = initial_space_; @@ -491,7 +542,7 @@ void RepeatedField<Element>::Swap(RepeatedField* other) { template <typename Element> void RepeatedField<Element>::SwapElements(int index1, int index2) { - swap(elements_[index1], elements_[index2]); + std::swap(elements_[index1], elements_[index2]); } template <typename Element> @@ -520,19 +571,40 @@ inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const { return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0; } +// Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant +// amount of code bloat. template <typename Element> -inline void RepeatedField<Element>::Reserve(int new_size) { +void RepeatedField<Element>::Reserve(int new_size) { if (total_size_ >= new_size) return; Element* old_elements = elements_; total_size_ = max(total_size_ * 2, new_size); elements_ = new Element[total_size_]; - memcpy(elements_, old_elements, current_size_ * sizeof(elements_[0])); + MoveArray(elements_, old_elements, current_size_); if (old_elements != initial_space_) { delete [] old_elements; } } +template <typename Element> +inline void RepeatedField<Element>::Truncate(int new_size) { + GOOGLE_DCHECK_LE(new_size, current_size_); + current_size_ = new_size; +} + +template <typename Element> +inline void RepeatedField<Element>::MoveArray( + Element to[], Element from[], int size) { + memcpy(to, from, size * sizeof(Element)); +} + +template <typename Element> +inline void RepeatedField<Element>::CopyArray( + Element to[], const Element from[], int size) { + memcpy(to, from, size * sizeof(Element)); +} + + // ------------------------------------------------------------------- namespace internal { @@ -600,17 +672,25 @@ void RepeatedPtrFieldBase::Clear() { } template <typename TypeHandler> -void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { +inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { Reserve(current_size_ + other.current_size_); for (int i = 0; i < other.current_size_; i++) { TypeHandler::Merge(other.Get<TypeHandler>(i), Add<TypeHandler>()); } } +inline int RepeatedPtrFieldBase::Capacity() const { + return total_size_; +} + inline void* const* RepeatedPtrFieldBase::raw_data() const { return elements_; } +inline void** RepeatedPtrFieldBase::raw_mutable_data() const { + return elements_; +} + template <typename TypeHandler> inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() { // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this @@ -627,7 +707,7 @@ RepeatedPtrFieldBase::data() const { } inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) { - swap(elements_[index1], elements_[index2]); + std::swap(elements_[index1], elements_[index2]); } template <typename TypeHandler> @@ -650,15 +730,29 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() { } template <typename TypeHandler> -inline void RepeatedPtrFieldBase::AddAllocated( +void RepeatedPtrFieldBase::AddAllocated( typename TypeHandler::Type* value) { - if (allocated_size_ == total_size_) Reserve(total_size_ + 1); - // We don't care about the order of cleared elements, so if there's one - // in the way, just move it to the back of the array. - if (current_size_ < allocated_size_) { + // Make room for the new pointer. + if (current_size_ == total_size_) { + // The array is completely full with no cleared objects, so grow it. + Reserve(total_size_ + 1); + ++allocated_size_; + } else if (allocated_size_ == total_size_) { + // There is no more space in the pointer array because it contains some + // cleared objects awaiting reuse. We don't want to grow the array in this + // case because otherwise a loop calling AddAllocated() followed by Clear() + // would leak memory. + TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_])); + } else if (current_size_ < allocated_size_) { + // We have some cleared objects. We don't care about their order, so we + // can just move the first one to the end to make space. elements_[allocated_size_] = elements_[current_size_]; + ++allocated_size_; + } else { + // There are no cleared objects. + ++allocated_size_; } - ++allocated_size_; + elements_[current_size_++] = value; } @@ -677,7 +771,7 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() { } -inline int RepeatedPtrFieldBase::ClearedCount() { +inline int RepeatedPtrFieldBase::ClearedCount() const { return allocated_size_ - current_size_; } @@ -694,18 +788,6 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() { return cast<TypeHandler>(elements_[--allocated_size_]); } -inline void RepeatedPtrFieldBase::Reserve(int new_size) { - if (total_size_ >= new_size) return; - - void** old_elements = elements_; - total_size_ = max(total_size_ * 2, new_size); - elements_ = new void*[total_size_]; - memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0])); - if (old_elements != initial_space_) { - delete [] old_elements; - } -} - } // namespace internal // ------------------------------------------------------------------- @@ -720,9 +802,7 @@ class RepeatedPtrField<string>::TypeHandler template <typename Element> -inline RepeatedPtrField<Element>::RepeatedPtrField() - : prototype_(NULL) { -} +inline RepeatedPtrField<Element>::RepeatedPtrField() {} template <typename Element> RepeatedPtrField<Element>::~RepeatedPtrField() { @@ -802,7 +882,7 @@ inline Element* RepeatedPtrField<Element>::ReleaseLast() { template <typename Element> -inline int RepeatedPtrField<Element>::ClearedCount() { +inline int RepeatedPtrField<Element>::ClearedCount() const { return RepeatedPtrFieldBase::ClearedCount(); } @@ -821,6 +901,11 @@ inline void RepeatedPtrField<Element>::Reserve(int new_size) { return RepeatedPtrFieldBase::Reserve(new_size); } +template <typename Element> +inline int RepeatedPtrField<Element>::Capacity() const { + return RepeatedPtrFieldBase::Capacity(); +} + // ------------------------------------------------------------------- namespace internal { @@ -921,6 +1006,84 @@ class RepeatedPtrIterator void* const* it_; }; +// Provide an iterator that operates on pointers to the underlying objects +// rather than the objects themselves as RepeatedPtrIterator does. +// Consider using this when working with stl algorithms that change +// the array. +template<typename Element> +class RepeatedPtrOverPtrsIterator + : public std::iterator<std::random_access_iterator_tag, Element*> { + public: + typedef RepeatedPtrOverPtrsIterator<Element> iterator; + typedef std::iterator< + std::random_access_iterator_tag, Element*> superclass; + + // Let the compiler know that these are type names, so we don't have to + // write "typename" in front of them everywhere. + typedef typename superclass::reference reference; + typedef typename superclass::pointer pointer; + typedef typename superclass::difference_type difference_type; + + RepeatedPtrOverPtrsIterator() : it_(NULL) {} + explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {} + + // dereferenceable + reference operator*() const { return *reinterpret_cast<Element**>(it_); } + pointer operator->() const { return &(operator*()); } + + // {inc,dec}rementable + iterator& operator++() { ++it_; return *this; } + iterator operator++(int) { return iterator(it_++); } + iterator& operator--() { --it_; return *this; } + iterator operator--(int) { return iterator(it_--); } + + // equality_comparable + bool operator==(const iterator& x) const { return it_ == x.it_; } + bool operator!=(const iterator& x) const { return it_ != x.it_; } + + // less_than_comparable + bool operator<(const iterator& x) const { return it_ < x.it_; } + bool operator<=(const iterator& x) const { return it_ <= x.it_; } + bool operator>(const iterator& x) const { return it_ > x.it_; } + bool operator>=(const iterator& x) const { return it_ >= x.it_; } + + // addable, subtractable + iterator& operator+=(difference_type d) { + it_ += d; + return *this; + } + friend iterator operator+(iterator it, difference_type d) { + it += d; + return it; + } + friend iterator operator+(difference_type d, iterator it) { + it += d; + return it; + } + iterator& operator-=(difference_type d) { + it_ -= d; + return *this; + } + friend iterator operator-(iterator it, difference_type d) { + it -= d; + return it; + } + + // indexable + reference operator[](difference_type d) const { return *(*this + d); } + + // random access iterator + difference_type operator-(const iterator& x) const { return it_ - x.it_; } + + private: + template<typename OtherElement> + friend class RepeatedPtrIterator; + + // The internal iterator. + void** it_; +}; + + } // namespace internal template <typename Element> @@ -944,6 +1107,18 @@ RepeatedPtrField<Element>::end() const { return iterator(raw_data() + size()); } +template <typename Element> +inline typename RepeatedPtrField<Element>::pointer_iterator +RepeatedPtrField<Element>::pointer_begin() { + return pointer_iterator(raw_mutable_data()); +} +template <typename Element> +inline typename RepeatedPtrField<Element>::pointer_iterator +RepeatedPtrField<Element>::pointer_end() { + return pointer_iterator(raw_mutable_data() + size()); +} + + // Iterators and helper functions that follow the spirit of the STL // std::back_insert_iterator and std::back_inserter but are tailor-made // for RepeatedField and RepatedPtrField. Typical usage would be: diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 50f009b..7c35f60 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -37,6 +37,7 @@ #include <algorithm> #include <list> +#include <vector> #include <google/protobuf/repeated_field.h> @@ -241,6 +242,31 @@ TEST(RepeatedField, MutableDataIsMutable) { EXPECT_EQ(2, field.Get(0)); } +TEST(RepeatedField, Truncate) { + RepeatedField<int> field; + + field.Add(12); + field.Add(34); + field.Add(56); + field.Add(78); + EXPECT_EQ(4, field.size()); + + field.Truncate(3); + EXPECT_EQ(3, field.size()); + + field.Add(90); + EXPECT_EQ(4, field.size()); + EXPECT_EQ(90, field.Get(3)); + + // Truncations that don't change the size are allowed, but growing is not + // allowed. + field.Truncate(field.size()); +#ifdef GTEST_HAS_DEATH_TEST + EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size"); +#endif +} + + // =================================================================== // RepeatedPtrField tests. These pretty much just mirror the RepeatedField // tests above. @@ -443,6 +469,52 @@ TEST(RepeatedPtrField, ClearedElements) { EXPECT_EQ(field.ClearedCount(), 0); } +// Test all code paths in AddAllocated(). +TEST(RepeatedPtrField, AddAlocated) { + RepeatedPtrField<string> field; + while (field.size() < field.Capacity()) { + field.Add()->assign("filler"); + } + + int index = field.size(); + + // First branch: Field is at capacity with no cleared objects. + string* foo = new string("foo"); + field.AddAllocated(foo); + EXPECT_EQ(index + 1, field.size()); + EXPECT_EQ(0, field.ClearedCount()); + EXPECT_EQ(foo, &field.Get(index)); + + // Last branch: Field is not at capacity and there are no cleared objects. + string* bar = new string("bar"); + field.AddAllocated(bar); + ++index; + EXPECT_EQ(index + 1, field.size()); + EXPECT_EQ(0, field.ClearedCount()); + EXPECT_EQ(bar, &field.Get(index)); + + // Third branch: Field is not at capacity and there are no cleared objects. + field.RemoveLast(); + string* baz = new string("baz"); + field.AddAllocated(baz); + EXPECT_EQ(index + 1, field.size()); + EXPECT_EQ(1, field.ClearedCount()); + EXPECT_EQ(baz, &field.Get(index)); + + // Second branch: Field is at capacity but has some cleared objects. + while (field.size() < field.Capacity()) { + field.Add()->assign("filler2"); + } + field.RemoveLast(); + index = field.size(); + string* qux = new string("qux"); + field.AddAllocated(qux); + EXPECT_EQ(index + 1, field.size()); + // We should have discarded the cleared object. + EXPECT_EQ(0, field.ClearedCount()); + EXPECT_EQ(qux, &field.Get(index)); +} + TEST(RepeatedPtrField, MergeFrom) { RepeatedPtrField<string> source, destination; @@ -592,7 +664,6 @@ TEST_F(RepeatedPtrFieldIteratorTest, Comparable) { } // Uninitialized iterator does not point to any of the RepeatedPtrField. -// Dereferencing an uninitialized iterator crashes the process. TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { RepeatedPtrField<string>::iterator iter; EXPECT_TRUE(iter != proto_array_.begin()); @@ -600,9 +671,6 @@ TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { EXPECT_TRUE(iter != proto_array_.begin() + 2); EXPECT_TRUE(iter != proto_array_.begin() + 3); EXPECT_TRUE(iter != proto_array_.end()); -#ifdef GTEST_HAS_DEATH_TEST - ASSERT_DEATH(GOOGLE_LOG(INFO) << *iter, ""); -#endif } TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { @@ -618,6 +686,7 @@ TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { string v = "f"; RepeatedPtrField<string>::const_iterator it = lower_bound(proto_array_.begin(), proto_array_.end(), v); + EXPECT_EQ(*it, "n"); EXPECT_TRUE(it == proto_array_.begin() + 3); } @@ -628,6 +697,149 @@ TEST_F(RepeatedPtrFieldIteratorTest, Mutation) { EXPECT_EQ("qux", proto_array_.Get(0)); } +// ------------------------------------------------------------------- + +class RepeatedPtrFieldPtrsIteratorTest : public testing::Test { + protected: + virtual void SetUp() { + proto_array_.Add()->assign("foo"); + proto_array_.Add()->assign("bar"); + proto_array_.Add()->assign("baz"); + } + + RepeatedPtrField<string> proto_array_; +}; + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) { + RepeatedPtrField<string>::pointer_iterator iter = + proto_array_.pointer_begin(); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) { + RepeatedPtrField<string>::pointer_iterator iter = + proto_array_.pointer_begin(); + EXPECT_EQ("foo", **iter); + ++iter; + EXPECT_EQ("bar", **(iter++)); + EXPECT_EQ("baz", **iter); + ++iter; + EXPECT_TRUE(proto_array_.pointer_end() == iter); + EXPECT_EQ("baz", **(--proto_array_.pointer_end())); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) { + RepeatedPtrField<string>::pointer_iterator iter = + proto_array_.pointer_begin(); + RepeatedPtrField<string>::pointer_iterator iter2 = iter; + ++iter2; + ++iter2; + EXPECT_TRUE(iter + 2 == iter2); + EXPECT_TRUE(iter == iter2 - 2); + EXPECT_EQ("baz", *iter[2]); + EXPECT_EQ("baz", **(iter + 2)); + EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) { + RepeatedPtrField<string>::pointer_iterator iter = + proto_array_.pointer_begin(); + RepeatedPtrField<string>::pointer_iterator iter2 = iter + 1; + EXPECT_TRUE(iter == iter); + EXPECT_TRUE(iter != iter2); + EXPECT_TRUE(iter < iter2); + EXPECT_TRUE(iter <= iter2); + EXPECT_TRUE(iter <= iter); + EXPECT_TRUE(iter2 > iter); + EXPECT_TRUE(iter2 >= iter); + EXPECT_TRUE(iter >= iter); +} + +// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs. +// Dereferencing an uninitialized iterator crashes the process. +TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) { + RepeatedPtrField<string>::pointer_iterator iter; + EXPECT_TRUE(iter != proto_array_.pointer_begin()); + EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1); + EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2); + EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3); + EXPECT_TRUE(iter != proto_array_.pointer_end()); +} + + +// This comparison functor is required by the tests for RepeatedPtrOverPtrs. +// They operate on strings and need to compare strings as strings in +// any stl algorithm, even though the iterator returns a pointer to a string +// - i.e. *iter has type string*. +struct StringLessThan { + bool operator()(const string* z, const string& y) { + return *z < y; + } + bool operator()(const string* z, const string* y) { + return *z < *y; + } +}; + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) { + proto_array_.Clear(); + proto_array_.Add()->assign("a"); + proto_array_.Add()->assign("c"); + proto_array_.Add()->assign("d"); + proto_array_.Add()->assign("n"); + proto_array_.Add()->assign("p"); + proto_array_.Add()->assign("x"); + proto_array_.Add()->assign("y"); + + RepeatedPtrField<string>::pointer_iterator iter = + proto_array_.pointer_begin(); + string v = "f"; + RepeatedPtrField<string>::pointer_iterator it = + lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(), + &v, StringLessThan()); + + GOOGLE_CHECK(*it != NULL); + + EXPECT_EQ(**it, "n"); + EXPECT_TRUE(it == proto_array_.pointer_begin() + 3); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) { + RepeatedPtrField<string>::pointer_iterator iter = + proto_array_.pointer_begin(); + **iter = "qux"; + EXPECT_EQ("qux", proto_array_.Get(0)); + + EXPECT_EQ("bar", proto_array_.Get(1)); + EXPECT_EQ("baz", proto_array_.Get(2)); + ++iter; + delete *iter; + *iter = new string("a"); + ++iter; + delete *iter; + *iter = new string("b"); + EXPECT_EQ("a", proto_array_.Get(1)); + EXPECT_EQ("b", proto_array_.Get(2)); +} + +TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) { + proto_array_.Add()->assign("c"); + proto_array_.Add()->assign("d"); + proto_array_.Add()->assign("n"); + proto_array_.Add()->assign("p"); + proto_array_.Add()->assign("a"); + proto_array_.Add()->assign("y"); + proto_array_.Add()->assign("x"); + EXPECT_EQ("foo", proto_array_.Get(0)); + EXPECT_EQ("n", proto_array_.Get(5)); + EXPECT_EQ("x", proto_array_.Get(9)); + sort(proto_array_.pointer_begin(), + proto_array_.pointer_end(), + StringLessThan()); + EXPECT_EQ("a", proto_array_.Get(0)); + EXPECT_EQ("baz", proto_array_.Get(2)); + EXPECT_EQ("y", proto_array_.Get(9)); +} + + // ----------------------------------------------------------------------------- // Unit-tests for the insert iterators // google::protobuf::RepeatedFieldBackInserter, diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h index 83f5f38..a6a7d16 100644 --- a/src/google/protobuf/service.h +++ b/src/google/protobuf/service.h @@ -32,10 +32,14 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // -// This module declares the abstract interfaces underlying proto2 RPC -// services. These are intented to be independent of any particular RPC +// DEPRECATED: This module declares the abstract interfaces underlying proto2 +// RPC services. These are intented to be independent of any particular RPC // implementation, so that proto2 services can be used on top of a variety -// of implementations. +// of implementations. Starting with version 2.3.0, RPC implementations should +// not try to build on these, but should instead provide code generator plugins +// which generate code specific to the particular RPC implementation. This way +// the generated code can be more appropriate for the implementation in use +// and can avoid unnecessary layers of indirection. // // // When you use the protocol compiler to compile a service definition, it diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 964fb6a..551ee4a 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -83,24 +83,24 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 2002000 +#define GOOGLE_PROTOBUF_VERSION 2003000 // The minimum library version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2002000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2003000 // The minimum header version which works with the current version of // the library. This constant should only be used by protoc's C++ code // generator. -static const int kMinHeaderVersionForLibrary = 2002000; +static const int kMinHeaderVersionForLibrary = 2003000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2002000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2003000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 2002000; +static const int kMinHeaderVersionForProtoc = 2003000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. @@ -171,7 +171,13 @@ static const int64 kint64min = -kint64max - 1; static const uint32 kuint32max = 0xFFFFFFFFu; static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); -#undef GOOGLE_ATTRIBUTE_ALWAYS_INLINE +// ------------------------------------------------------------------- +// Annotations: Some parts of the code have been annotated in ways that might +// be useful to some compilers or tools, but are not supported universally. +// You can #define these annotations yourself if the default implementation +// is not right for you. + +#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE #if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) // For functions we want to force inline. // Introduced in gcc 3.1. @@ -180,14 +186,35 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); // Other compilers will have to figure it out for themselves. #define GOOGLE_ATTRIBUTE_ALWAYS_INLINE #endif +#endif -#undef GOOGLE_ATTRIBUTE_DEPRECATED +#ifndef GOOGLE_ATTRIBUTE_DEPRECATED #ifdef __GNUC__ // If the method/variable/type is used anywhere, produce a warning. #define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) #else #define GOOGLE_ATTRIBUTE_DEPRECATED #endif +#endif + +#ifndef GOOGLE_PREDICT_TRUE +#ifdef __GNUC__ +// Provided at least since GCC 3.0. +#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define GOOGLE_PREDICT_TRUE +#endif +#endif + +// Delimits a block of code which may write to memory which is simultaneously +// written by other threads, but which has been determined to be thread-safe +// (e.g. because it is an idempotent write). +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN +#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN() +#endif +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END +#define GOOGLE_SAFE_CONCURRENT_WRITES_END() +#endif // =================================================================== // from google3/base/basictypes.h @@ -283,7 +310,9 @@ inline To down_cast(From* f) { // so we only accept pointers implicit_cast<From*, To>(0); } +#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI) assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only! +#endif return static_cast<To>(f); } diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h index c341413..822d605 100644 --- a/src/google/protobuf/stubs/hash.h +++ b/src/google/protobuf/stubs/hash.h @@ -98,7 +98,7 @@ template <typename Key, class hash_set : public std::set<Key, HashFcn> { }; -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) template <typename Key> struct hash : public HASH_NAMESPACE::hash_compare<Key> { @@ -145,21 +145,30 @@ struct hash<const Key*> { } }; +// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So, +// we go ahead and provide our own implementation. template <> -struct hash<const char*> : public HASH_NAMESPACE::hash<const char*> { +struct hash<const char*> { + inline size_t operator()(const char* str) const { + size_t result = 0; + for (; *str != '\0'; str++) { + result = 5 * result + *str; + } + return result; + } }; template <typename Key, typename Data, typename HashFcn = hash<Key>, typename EqualKey = std::equal_to<Key> > -class hash_map : public HASH_NAMESPACE::hash_map< +class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS< Key, Data, HashFcn, EqualKey> { }; template <typename Key, typename HashFcn = hash<Key>, typename EqualKey = std::equal_to<Key> > -class hash_set : public HASH_NAMESPACE::hash_set< +class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS< Key, HashFcn, EqualKey> { }; diff --git a/src/google/protobuf/stubs/once.cc b/src/google/protobuf/stubs/once.cc index 3c53bcd..5b7af9c 100644 --- a/src/google/protobuf/stubs/once.cc +++ b/src/google/protobuf/stubs/once.cc @@ -46,33 +46,33 @@ namespace protobuf { #ifdef _WIN32 -struct GoogleOnceInternal { - GoogleOnceInternal() { +struct ProtobufOnceInternal { + ProtobufOnceInternal() { InitializeCriticalSection(&critical_section); } - ~GoogleOnceInternal() { + ~ProtobufOnceInternal() { DeleteCriticalSection(&critical_section); } CRITICAL_SECTION critical_section; }; -GoogleOnceType::~GoogleOnceType() +ProtobufOnceType::~ProtobufOnceType() { delete internal_; internal_ = NULL; } -GoogleOnceType::GoogleOnceType() { +ProtobufOnceType::ProtobufOnceType() { // internal_ may be non-NULL if Init() was already called. - if (internal_ == NULL) internal_ = new GoogleOnceInternal; + if (internal_ == NULL) internal_ = new ProtobufOnceInternal; } -void GoogleOnceType::Init(void (*init_func)()) { +void ProtobufOnceType::Init(void (*init_func)()) { // internal_ may be NULL if we're still in dynamic initialization and the // constructor has not been called yet. As mentioned in once.h, we assume // that the program is still single-threaded at this time, and therefore it // should be safe to initialize internal_ like so. - if (internal_ == NULL) internal_ = new GoogleOnceInternal; + if (internal_ == NULL) internal_ = new ProtobufOnceInternal; EnterCriticalSection(&internal_->critical_section); if (!initialized_) { diff --git a/src/google/protobuf/stubs/once.h b/src/google/protobuf/stubs/once.h index 22b0d4e..0dee407 100644 --- a/src/google/protobuf/stubs/once.h +++ b/src/google/protobuf/stubs/once.h @@ -38,13 +38,13 @@ // This is basically a portable version of pthread_once(). // // This header declares three things: -// * A type called GoogleOnceType. +// * A type called ProtobufOnceType. // * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type -// GoogleOnceType. This is the only legal way to declare such a variable. +// ProtobufOnceType. This is the only legal way to declare such a variable. // The macro may only be used at the global scope (you cannot create local // or class member variables of this type). -// * A function GogoleOnceInit(GoogleOnceType* once, void (*init_func)()). -// This function, when invoked multiple times given the same GoogleOnceType +// * A function GogoleOnceInit(ProtobufOnceType* once, void (*init_func)()). +// This function, when invoked multiple times given the same ProtobufOnceType // object, will invoke init_func on the first call only, and will make sure // none of the calls return before that first call to init_func has finished. // @@ -83,21 +83,21 @@ namespace protobuf { #ifdef _WIN32 -struct GoogleOnceInternal; +struct ProtobufOnceInternal; -struct LIBPROTOBUF_EXPORT GoogleOnceType { - GoogleOnceType(); - ~GoogleOnceType(); +struct LIBPROTOBUF_EXPORT ProtobufOnceType { + ProtobufOnceType(); + ~ProtobufOnceType(); void Init(void (*init_func)()); volatile bool initialized_; - GoogleOnceInternal* internal_; + ProtobufOnceInternal* internal_; }; #define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ - ::google::protobuf::GoogleOnceType NAME + ::google::protobuf::ProtobufOnceType NAME -inline void GoogleOnceInit(GoogleOnceType* once, void (*init_func)()) { +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { // Note: Double-checked locking is safe on x86. if (!once->initialized_) { once->Init(init_func); @@ -106,12 +106,12 @@ inline void GoogleOnceInit(GoogleOnceType* once, void (*init_func)()) { #else -typedef pthread_once_t GoogleOnceType; +typedef pthread_once_t ProtobufOnceType; #define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ pthread_once_t NAME = PTHREAD_ONCE_INIT -inline void GoogleOnceInit(GoogleOnceType* once, void (*init_func)()) { +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { pthread_once(once, init_func); } diff --git a/src/google/protobuf/stubs/once_unittest.cc b/src/google/protobuf/stubs/once_unittest.cc index 86e0647..b8f86a0 100644 --- a/src/google/protobuf/stubs/once_unittest.cc +++ b/src/google/protobuf/stubs/once_unittest.cc @@ -52,10 +52,10 @@ class OnceInitTest : public testing::Test { current_test_ = this; } - // Since GoogleOnceType is only allowed to be allocated in static storage, - // each test must use a different pair of GoogleOnceType objects which it + // Since ProtobufOnceType is only allowed to be allocated in static storage, + // each test must use a different pair of ProtobufOnceType objects which it // must declare itself. - void SetOnces(GoogleOnceType* once, GoogleOnceType* recursive_once) { + void SetOnces(ProtobufOnceType* once, ProtobufOnceType* recursive_once) { once_ = once; recursive_once_ = recursive_once; } @@ -155,8 +155,8 @@ class OnceInitTest : public testing::Test { Mutex mutex_; Mutex init_blocker_; State state_; - GoogleOnceType* once_; - GoogleOnceType* recursive_once_; + ProtobufOnceType* once_; + ProtobufOnceType* recursive_once_; void Init() { MutexLock lock(&mutex_); diff --git a/src/google/protobuf/stubs/structurally_valid.cc b/src/google/protobuf/stubs/structurally_valid.cc index e385a81..0f6afe6 100644 --- a/src/google/protobuf/stubs/structurally_valid.cc +++ b/src/google/protobuf/stubs/structurally_valid.cc @@ -371,36 +371,44 @@ int UTF8GenericScan(const UTF8ScanObj* st, // Do state-table scan int e = 0; uint8 c; - - // Do fast for groups of 8 identity bytes. - // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop, - // including slowing slightly on cr/lf/ht - //---------------------------- const uint8* Tbl2 = &st->fast_state[0]; - uint32 losub = st->losub; - uint32 hiadd = st->hiadd; - while (src < srclimit8) { - uint32 s0123 = (reinterpret_cast<const uint32 *>(src))[0]; - uint32 s4567 = (reinterpret_cast<const uint32 *>(src))[1]; - src += 8; - // This is a fast range check for all bytes in [lowsub..0x80-hiadd) - uint32 temp = (s0123 - losub) | (s0123 + hiadd) | - (s4567 - losub) | (s4567 + hiadd); - if ((temp & 0x80808080) != 0) { - // We typically end up here on cr/lf/ht; src was incremented - int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) | - (Tbl2[src[-6]] | Tbl2[src[-5]]); - if (e0123 != 0) { - src -= 8; - break; - } // Exit on Non-interchange - e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) | - (Tbl2[src[-2]] | Tbl2[src[-1]]); - if (e0123 != 0) { - src -= 4; - break; - } // Exit on Non-interchange - // Else OK, go around again + const uint32 losub = st->losub; + const uint32 hiadd = st->hiadd; + // Check initial few bytes one at a time until 8-byte aligned + //---------------------------- + while ((((uintptr_t)src & 0x07) != 0) && + (src < srclimit) && + Tbl2[src[0]] == 0) { + src++; + } + if (((uintptr_t)src & 0x07) == 0) { + // Do fast for groups of 8 identity bytes. + // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop, + // including slowing slightly on cr/lf/ht + //---------------------------- + while (src < srclimit8) { + uint32 s0123 = (reinterpret_cast<const uint32 *>(src))[0]; + uint32 s4567 = (reinterpret_cast<const uint32 *>(src))[1]; + src += 8; + // This is a fast range check for all bytes in [lowsub..0x80-hiadd) + uint32 temp = (s0123 - losub) | (s0123 + hiadd) | + (s4567 - losub) | (s4567 + hiadd); + if ((temp & 0x80808080) != 0) { + // We typically end up here on cr/lf/ht; src was incremented + int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) | + (Tbl2[src[-6]] | Tbl2[src[-5]]); + if (e0123 != 0) { + src -= 8; + break; + } // Exit on Non-interchange + e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) | + (Tbl2[src[-2]] | Tbl2[src[-1]]); + if (e0123 != 0) { + src -= 4; + break; + } // Exit on Non-interchange + // Else OK, go around again + } } } //---------------------------- @@ -470,10 +478,17 @@ int UTF8GenericScanFastAscii(const UTF8ScanObj* st, int rest_consumed; int exit_reason; do { - while ((src < srclimit8) && - (((reinterpret_cast<const uint32*>(src)[0] | - reinterpret_cast<const uint32*>(src)[1]) & 0x80808080) == 0)) { - src += 8; + // Check initial few bytes one at a time until 8-byte aligned + while ((((uintptr_t)src & 0x07) != 0) && + (src < srclimit) && (src[0] < 0x80)) { + src++; + } + if (((uintptr_t)src & 0x07) == 0) { + while ((src < srclimit8) && + (((reinterpret_cast<const uint32*>(src)[0] | + reinterpret_cast<const uint32*>(src)[1]) & 0x80808080) == 0)) { + src += 8; + } } while ((src < srclimit) && (src[0] < 0x80)) { src++; diff --git a/src/google/protobuf/stubs/structurally_valid_unittest.cc b/src/google/protobuf/stubs/structurally_valid_unittest.cc index 2282551..9088888 100644 --- a/src/google/protobuf/stubs/structurally_valid_unittest.cc +++ b/src/google/protobuf/stubs/structurally_valid_unittest.cc @@ -13,15 +13,25 @@ TEST(StructurallyValidTest, ValidUTF8String) { // On GCC, this string can be written as: // "abcd 1234 - \u2014\u2013\u2212" // MSVC seems to interpret \u differently. - string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222"); + string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(), valid_str.size())); + // Additional check for pointer alignment + for (int i = 1; i < 8; ++i) { + EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data() + i, + valid_str.size() - i)); + } } TEST(StructurallyValidTest, InvalidUTF8String) { - string invalid_str("\xA0\xB0"); + const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(), invalid_str.size())); + // Additional check for pointer alignment + for (int i = 1; i < 8; ++i) { + EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data() + i, + invalid_str.size() - i)); + } } } // namespace diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index a476475..bb658ba 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -36,6 +36,7 @@ #include <limits> #include <limits.h> #include <stdio.h> +#include <iterator> #ifdef _WIN32 // MSVC has only _snprintf, not snprintf. @@ -424,8 +425,8 @@ string UnescapeCEscapeString(const string& src) { // // Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. // ---------------------------------------------------------------------- -static int CEscapeInternal(const char* src, int src_len, char* dest, - int dest_len, bool use_hex) { +int CEscapeInternal(const char* src, int src_len, char* dest, + int dest_len, bool use_hex, bool utf8_safe) { const char* src_end = src + src_len; int used = 0; bool last_hex_escape = false; // true if last output char was \xNN @@ -446,7 +447,9 @@ static int CEscapeInternal(const char* src, int src_len, char* dest, // Note that if we emit \xNN and the src character after that is a hex // digit then that digit must be escaped too to prevent it being // interpreted as part of the character code by C. - if (!isprint(*src) || (last_hex_escape && isxdigit(*src))) { + if ((!utf8_safe || static_cast<uint8>(*src) < 0x80) && + (!isprint(*src) || + (last_hex_escape && isxdigit(*src)))) { if (dest_len - used < 4) // need space for 4 letter escape return -1; sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), @@ -468,7 +471,7 @@ static int CEscapeInternal(const char* src, int src_len, char* dest, } int CEscapeString(const char* src, int src_len, char* dest, int dest_len) { - return CEscapeInternal(src, src_len, dest, dest_len, false); + return CEscapeInternal(src, src_len, dest, dest_len, false, false); } // ---------------------------------------------------------------------- @@ -485,11 +488,33 @@ string CEscape(const string& src) { const int dest_length = src.size() * 4 + 1; // Maximum possible expansion scoped_array<char> dest(new char[dest_length]); const int len = CEscapeInternal(src.data(), src.size(), - dest.get(), dest_length, false); + dest.get(), dest_length, false, false); GOOGLE_DCHECK_GE(len, 0); return string(dest.get(), len); } +namespace strings { + +string Utf8SafeCEscape(const string& src) { + const int dest_length = src.size() * 4 + 1; // Maximum possible expansion + scoped_array<char> dest(new char[dest_length]); + const int len = CEscapeInternal(src.data(), src.size(), + dest.get(), dest_length, false, true); + GOOGLE_DCHECK_GE(len, 0); + return string(dest.get(), len); +} + +string CHexEscape(const string& src) { + const int dest_length = src.size() * 4 + 1; // Maximum possible expansion + scoped_array<char> dest(new char[dest_length]); + const int len = CEscapeInternal(src.data(), src.size(), + dest.get(), dest_length, true, false); + GOOGLE_DCHECK_GE(len, 0); + return string(dest.get(), len); +} + +} // namespace strings + // ---------------------------------------------------------------------- // strto32_adaptor() // strtou32_adaptor() @@ -1027,7 +1052,7 @@ char* DoubleToBuffer(double value, char* buffer) { bool safe_strtof(const char* str, float* value) { char* endptr; errno = 0; // errno only gets set on errors -#ifdef _WIN32 // has no strtof() +#if defined(_WIN32) || defined (__hpux) // has no strtof() *value = strtod(str, &endptr); #else *value = strtof(str, &endptr); diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index 7f6bd96..777694b 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h @@ -33,6 +33,7 @@ #ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ #define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ +#include <stdlib.h> #include <vector> #include <google/protobuf/stubs/common.h> @@ -264,6 +265,14 @@ LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len, // ---------------------------------------------------------------------- LIBPROTOBUF_EXPORT string CEscape(const string& src); +namespace strings { +// Like CEscape() but does not escape bytes with the upper bit set. +LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src); + +// Like CEscape() but uses hex (\x) escapes instead of octals. +LIBPROTOBUF_EXPORT string CHexEscape(const string& src); +} // namespace strings + // ---------------------------------------------------------------------- // strto32() // strtou32() diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc index 0637c0a..af8b390 100644 --- a/src/google/protobuf/test_util.cc +++ b/src/google/protobuf/test_util.cc @@ -229,11 +229,11 @@ void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) { message->GetReflection()->SetRepeatedString( message, message->GetDescriptor()->FindFieldByName("repeated_string_piece"), - 1, "424"); + 1, "524"); message->GetReflection()->SetRepeatedString( message, message->GetDescriptor()->FindFieldByName("repeated_cord"), - 1, "425"); + 1, "525"); #endif // !PROTOBUF_TEST_NO_DESCRIPTORS } @@ -692,6 +692,40 @@ void TestUtil::SetPackedFields(unittest::TestPackedTypes* message) { message->add_packed_enum (unittest::FOREIGN_BAZ); } +void TestUtil::SetUnpackedFields(unittest::TestUnpackedTypes* message) { + // The values applied here must match those of SetPackedFields. + + message->add_unpacked_int32 (601); + message->add_unpacked_int64 (602); + message->add_unpacked_uint32 (603); + message->add_unpacked_uint64 (604); + message->add_unpacked_sint32 (605); + message->add_unpacked_sint64 (606); + message->add_unpacked_fixed32 (607); + message->add_unpacked_fixed64 (608); + message->add_unpacked_sfixed32(609); + message->add_unpacked_sfixed64(610); + message->add_unpacked_float (611); + message->add_unpacked_double (612); + message->add_unpacked_bool (true); + message->add_unpacked_enum (unittest::FOREIGN_BAR); + // add a second one of each field + message->add_unpacked_int32 (701); + message->add_unpacked_int64 (702); + message->add_unpacked_uint32 (703); + message->add_unpacked_uint64 (704); + message->add_unpacked_sint32 (705); + message->add_unpacked_sint64 (706); + message->add_unpacked_fixed32 (707); + message->add_unpacked_fixed64 (708); + message->add_unpacked_sfixed32(709); + message->add_unpacked_sfixed64(710); + message->add_unpacked_float (711); + message->add_unpacked_double (712); + message->add_unpacked_bool (false); + message->add_unpacked_enum (unittest::FOREIGN_BAZ); +} + // ------------------------------------------------------------------- void TestUtil::ModifyPackedFields(unittest::TestPackedTypes* message) { @@ -760,6 +794,56 @@ void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) { EXPECT_EQ(unittest::FOREIGN_BAZ, message.packed_enum(1)); } +void TestUtil::ExpectUnpackedFieldsSet( + const unittest::TestUnpackedTypes& message) { + // The values expected here must match those of ExpectPackedFieldsSet. + + ASSERT_EQ(2, message.unpacked_int32_size ()); + ASSERT_EQ(2, message.unpacked_int64_size ()); + ASSERT_EQ(2, message.unpacked_uint32_size ()); + ASSERT_EQ(2, message.unpacked_uint64_size ()); + ASSERT_EQ(2, message.unpacked_sint32_size ()); + ASSERT_EQ(2, message.unpacked_sint64_size ()); + ASSERT_EQ(2, message.unpacked_fixed32_size ()); + ASSERT_EQ(2, message.unpacked_fixed64_size ()); + ASSERT_EQ(2, message.unpacked_sfixed32_size()); + ASSERT_EQ(2, message.unpacked_sfixed64_size()); + ASSERT_EQ(2, message.unpacked_float_size ()); + ASSERT_EQ(2, message.unpacked_double_size ()); + ASSERT_EQ(2, message.unpacked_bool_size ()); + ASSERT_EQ(2, message.unpacked_enum_size ()); + + EXPECT_EQ(601 , message.unpacked_int32 (0)); + EXPECT_EQ(602 , message.unpacked_int64 (0)); + EXPECT_EQ(603 , message.unpacked_uint32 (0)); + EXPECT_EQ(604 , message.unpacked_uint64 (0)); + EXPECT_EQ(605 , message.unpacked_sint32 (0)); + EXPECT_EQ(606 , message.unpacked_sint64 (0)); + EXPECT_EQ(607 , message.unpacked_fixed32 (0)); + EXPECT_EQ(608 , message.unpacked_fixed64 (0)); + EXPECT_EQ(609 , message.unpacked_sfixed32(0)); + EXPECT_EQ(610 , message.unpacked_sfixed64(0)); + EXPECT_EQ(611 , message.unpacked_float (0)); + EXPECT_EQ(612 , message.unpacked_double (0)); + EXPECT_EQ(true , message.unpacked_bool (0)); + EXPECT_EQ(unittest::FOREIGN_BAR, message.unpacked_enum(0)); + + EXPECT_EQ(701 , message.unpacked_int32 (1)); + EXPECT_EQ(702 , message.unpacked_int64 (1)); + EXPECT_EQ(703 , message.unpacked_uint32 (1)); + EXPECT_EQ(704 , message.unpacked_uint64 (1)); + EXPECT_EQ(705 , message.unpacked_sint32 (1)); + EXPECT_EQ(706 , message.unpacked_sint64 (1)); + EXPECT_EQ(707 , message.unpacked_fixed32 (1)); + EXPECT_EQ(708 , message.unpacked_fixed64 (1)); + EXPECT_EQ(709 , message.unpacked_sfixed32(1)); + EXPECT_EQ(710 , message.unpacked_sfixed64(1)); + EXPECT_EQ(711 , message.unpacked_float (1)); + EXPECT_EQ(712 , message.unpacked_double (1)); + EXPECT_EQ(false, message.unpacked_bool (1)); + EXPECT_EQ(unittest::FOREIGN_BAZ, message.unpacked_enum(1)); +} + // ------------------------------------------------------------------- void TestUtil::ExpectPackedClear( diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h index 5a6ec88..25165f3 100644 --- a/src/google/protobuf/test_util.h +++ b/src/google/protobuf/test_util.h @@ -54,6 +54,7 @@ class TestUtil { static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message); static void SetPackedFields(unittest::TestPackedTypes* message); static void SetPackedExtensions(unittest::TestPackedExtensions* message); + static void SetUnpackedFields(unittest::TestUnpackedTypes* message); // Use the repeated versions of the set_*() accessors to modify all the // repeated fields of the messsage (which should already have been @@ -72,6 +73,8 @@ class TestUtil { static void ExpectPackedFieldsSet(const unittest::TestPackedTypes& message); static void ExpectPackedExtensionsSet( const unittest::TestPackedExtensions& message); + static void ExpectUnpackedFieldsSet( + const unittest::TestUnpackedTypes& message); // Expect that the message is modified as would be expected from // Modify*Fields(). diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc index f813e8e..e224781 100644 --- a/src/google/protobuf/testing/file.cc +++ b/src/google/protobuf/testing/file.cc @@ -84,10 +84,13 @@ void File::ReadFileToStringOrDie(const string& name, string* output) { void File::WriteStringToFileOrDie(const string& contents, const string& name) { FILE* file = fopen(name.c_str(), "wb"); - GOOGLE_CHECK(file != NULL); + GOOGLE_CHECK(file != NULL) + << "fopen(" << name << ", \"wb\"): " << strerror(errno); GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file), - contents.size()); - GOOGLE_CHECK(fclose(file) == 0); + contents.size()) + << "fwrite(" << name << "): " << strerror(errno); + GOOGLE_CHECK(fclose(file) == 0) + << "fclose(" << name << "): " << strerror(errno); } bool File::CreateDir(const string& name, int mode) { @@ -97,8 +100,10 @@ bool File::CreateDir(const string& name, int mode) { bool File::RecursivelyCreateDir(const string& path, int mode) { if (CreateDir(path, mode)) return true; + if (Exists(path)) return false; + // Try creating the parent. - string::size_type slashpos = path.find_first_of('/'); + string::size_type slashpos = path.find_last_of('/'); if (slashpos == string::npos) { // No parent given. return false; diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc index 1339b33..cd094d0 100644 --- a/src/google/protobuf/testing/googletest.cc +++ b/src/google/protobuf/testing/googletest.cc @@ -46,6 +46,8 @@ #endif #include <stdio.h> #include <fcntl.h> +#include <iostream> +#include <fstream> namespace google { namespace protobuf { @@ -94,7 +96,8 @@ string GetTemporaryDirectoryName() { // tmpnam() is generally not considered safe but we're only using it for // testing. We cannot use tmpfile() or mkstemp() since we're creating a // directory. - string result = tmpnam(NULL); + char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0 + string result = tmpnam(b); #ifdef _WIN32 // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed // to be used in the current working directory. WTF? diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index cf75402..137cbce 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -54,21 +54,19 @@ namespace protobuf { string Message::DebugString() const { string debug_string; - io::StringOutputStream output_stream(&debug_string); - TextFormat::Print(*this, &output_stream); + TextFormat::PrintToString(*this, &debug_string); return debug_string; } string Message::ShortDebugString() const { string debug_string; - io::StringOutputStream output_stream(&debug_string); TextFormat::Printer printer; printer.SetSingleLineMode(true); - printer.Print(*this, &output_stream); + printer.PrintToString(*this, &debug_string); // Single line mode currently might have an extra space at the end. if (debug_string.size() > 0 && debug_string[debug_string.size() - 1] == ' ') { @@ -78,10 +76,22 @@ string Message::ShortDebugString() const { return debug_string; } +string Message::Utf8DebugString() const { + string debug_string; + + TextFormat::Printer printer; + printer.SetUseUtf8StringEscaping(true); + + printer.PrintToString(*this, &debug_string); + + return debug_string; +} + void Message::PrintDebugString() const { printf("%s", DebugString().c_str()); } + // =========================================================================== // Internal class for parsing an ASCII representation of a Protocol Message. // This class makes use of the Protocol Message compiler's tokenizer found @@ -170,6 +180,23 @@ class TextFormat::Parser::ParserImpl { } } + void ReportWarning(int line, int col, const string& message) { + if (error_collector_ == NULL) { + if (line >= 0) { + GOOGLE_LOG(WARNING) << "Warning parsing text-format " + << root_message_type_->full_name() + << ": " << (line + 1) << ":" + << (col + 1) << ": " << message; + } else { + GOOGLE_LOG(WARNING) << "Warning parsing text-format " + << root_message_type_->full_name() + << ": " << message; + } + } else { + error_collector_->AddWarning(line, col, message); + } + } + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); @@ -180,6 +207,13 @@ class TextFormat::Parser::ParserImpl { message); } + // Reports a warning with the given message with information indicating + // the position (as derived from the current token). + void ReportWarning(const string& message) { + ReportWarning(tokenizer_.current().line, tokenizer_.current().column, + message); + } + // Consumes the specified message with the given starting delimeter. // This method checks to see that the end delimeter at the conclusion of // the consumption matches the starting delimeter passed in here. @@ -270,6 +304,11 @@ class TextFormat::Parser::ParserImpl { DO(ConsumeFieldValue(message, reflection, field)); } + if (field->options().deprecated()) { + ReportWarning("text format contains deprecated field \"" + + field_name + "\""); + } + return true; } @@ -583,6 +622,10 @@ class TextFormat::Parser::ParserImpl { parser_->ReportError(line, column, message); } + virtual void AddWarning(int line, int column, const string& message) { + parser_->ReportWarning(line, column, message); + } + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); TextFormat::Parser::ParserImpl* parser_; @@ -644,12 +687,16 @@ class TextFormat::Printer::TextGenerator { // Print text to the output stream. void Print(const string& str) { - Print(str.c_str()); + Print(str.data(), str.size()); } // Print text to the output stream. void Print(const char* text) { - int size = strlen(text); + Print(text, strlen(text)); + } + + // Print text to the output stream. + void Print(const char* text, int size) { int pos = 0; // The number of bytes we've written so far. for (int i = 0; i < size; i++) { @@ -799,7 +846,9 @@ bool TextFormat::Parser::ParseFieldValueFromString( TextFormat::Printer::Printer() : initial_indent_level_(0), - single_line_mode_(false) {} + single_line_mode_(false), + use_short_repeated_primitives_(false), + utf8_string_escaping_(false) {} TextFormat::Printer::~Printer() {} @@ -876,6 +925,14 @@ void TextFormat::Printer::PrintField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, TextGenerator& generator) { + if (use_short_repeated_primitives_ && + field->is_repeated() && + field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && + field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + PrintShortRepeatedField(message, reflection, field, generator); + return; + } + int count = 0; if (field->is_repeated()) { @@ -885,26 +942,7 @@ void TextFormat::Printer::PrintField(const Message& message, } for (int j = 0; j < count; ++j) { - if (field->is_extension()) { - generator.Print("["); - // We special-case MessageSet elements for compatibility with proto1. - if (field->containing_type()->options().message_set_wire_format() - && field->type() == FieldDescriptor::TYPE_MESSAGE - && field->is_optional() - && field->extension_scope() == field->message_type()) { - generator.Print(field->message_type()->full_name()); - } else { - generator.Print(field->full_name()); - } - generator.Print("]"); - } else { - if (field->type() == FieldDescriptor::TYPE_GROUP) { - // Groups must be serialized with their original capitalization. - generator.Print(field->message_type()->name()); - } else { - generator.Print(field->name()); - } - } + PrintFieldName(message, reflection, field, generator); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (single_line_mode_) { @@ -926,16 +964,64 @@ void TextFormat::Printer::PrintField(const Message& message, PrintFieldValue(message, reflection, field, field_index, generator); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (!single_line_mode_) { + if (single_line_mode_) { + generator.Print("} "); + } else { generator.Outdent(); + generator.Print("}\n"); + } + } else { + if (single_line_mode_) { + generator.Print(" "); + } else { + generator.Print("\n"); } - generator.Print("}"); } + } +} - if (single_line_mode_) { - generator.Print(" "); +void TextFormat::Printer::PrintShortRepeatedField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) { + // Print primitive repeated field in short form. + PrintFieldName(message, reflection, field, generator); + + int size = reflection->FieldSize(message, field); + generator.Print(": ["); + for (int i = 0; i < size; i++) { + if (i > 0) generator.Print(", "); + PrintFieldValue(message, reflection, field, i, generator); + } + if (single_line_mode_) { + generator.Print("] "); + } else { + generator.Print("]\n"); + } +} + +void TextFormat::Printer::PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) { + if (field->is_extension()) { + generator.Print("["); + // We special-case MessageSet elements for compatibility with proto1. + if (field->containing_type()->options().message_set_wire_format() + && field->type() == FieldDescriptor::TYPE_MESSAGE + && field->is_optional() + && field->extension_scope() == field->message_type()) { + generator.Print(field->message_type()->full_name()); + } else { + generator.Print(field->full_name()); + } + generator.Print("]"); + } else { + if (field->type() == FieldDescriptor::TYPE_GROUP) { + // Groups must be serialized with their original capitalization. + generator.Print(field->message_type()->name()); } else { - generator.Print("\n"); + generator.Print(field->name()); } } } @@ -973,7 +1059,11 @@ void TextFormat::Printer::PrintFieldValue( reflection->GetStringReference(message, field, &scratch); generator.Print("\""); - generator.Print(CEscape(value)); + if (utf8_string_escaping_) { + generator.Print(strings::Utf8SafeCEscape(value)); + } else { + generator.Print(CEscape(value)); + } generator.Print("\""); break; diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index 39a039d..e78e104 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -117,6 +117,24 @@ class LIBPROTOBUF_EXPORT TextFormat { single_line_mode_ = single_line_mode; } + // Set true to print repeated primitives in a format like: + // field_name: [1, 2, 3, 4] + // instead of printing each value on its own line. Short format applies + // only to primitive values -- i.e. everything except strings and + // sub-messages/groups. Note that at present this format is not recognized + // by the parser. + void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { + use_short_repeated_primitives_ = use_short_repeated_primitives; + } + + // Set true to output UTF-8 instead of ASCII. The only difference + // is that bytes >= 0x80 in string fields will not be escaped, + // because they are assumed to be part of UTF-8 multi-byte + // sequences. + void SetUseUtf8StringEscaping(bool as_utf8) { + utf8_string_escaping_ = as_utf8; + } + private: // Forward declaration of an internal class used to print the text // output to the OutputStream (see text_format.cc for implementation). @@ -133,6 +151,19 @@ class LIBPROTOBUF_EXPORT TextFormat { const FieldDescriptor* field, TextGenerator& generator); + // Print a repeated primitive field in short form. + void PrintShortRepeatedField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator); + + // Print the name of a field -- i.e. everything that comes before the + // ':' for a single name/value pair. + void PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator); + // Outputs a textual representation of the value of the field supplied on // the message supplied or the default value if not set. void PrintFieldValue(const Message& message, @@ -150,6 +181,10 @@ class LIBPROTOBUF_EXPORT TextFormat { int initial_indent_level_; bool single_line_mode_; + + bool use_short_repeated_primitives_; + + bool utf8_string_escaping_; }; // Parses a text-format protocol message from the given input stream to diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 7c31e80..ddf8ff7 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -138,12 +138,53 @@ TEST_F(TextFormatTest, ShortDebugString) { proto_.ShortDebugString()); } +TEST_F(TextFormatTest, ShortPrimitiveRepeateds) { + proto_.set_optional_int32(123); + proto_.add_repeated_int32(456); + proto_.add_repeated_int32(789); + proto_.add_repeated_string("foo"); + proto_.add_repeated_string("bar"); + proto_.add_repeated_nested_message()->set_bb(2); + proto_.add_repeated_nested_message()->set_bb(3); + proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO); + proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR); + + TextFormat::Printer printer; + printer.SetUseShortRepeatedPrimitives(true); + string text; + printer.PrintToString(proto_, &text); + + EXPECT_EQ("optional_int32: 123\n" + "repeated_int32: [456, 789]\n" + "repeated_string: \"foo\"\n" + "repeated_string: \"bar\"\n" + "repeated_nested_message {\n bb: 2\n}\n" + "repeated_nested_message {\n bb: 3\n}\n" + "repeated_nested_enum: [FOO, BAR]\n", + text); + + // Try in single-line mode. + printer.SetSingleLineMode(true); + printer.PrintToString(proto_, &text); + + EXPECT_EQ("optional_int32: 123 " + "repeated_int32: [456, 789] " + "repeated_string: \"foo\" " + "repeated_string: \"bar\" " + "repeated_nested_message { bb: 2 } " + "repeated_nested_message { bb: 3 } " + "repeated_nested_enum: [FOO, BAR] ", + text); +} + + TEST_F(TextFormatTest, StringEscape) { // Set the string value to test. proto_.set_optional_string(kEscapeTestString); // Get the DebugString from the proto. string debug_string = proto_.DebugString(); + string utf8_debug_string = proto_.Utf8DebugString(); // Hardcode a correct value to test against. string correct_string = "optional_string: " @@ -152,12 +193,36 @@ TEST_F(TextFormatTest, StringEscape) { // Compare. EXPECT_EQ(correct_string, debug_string); + // UTF-8 string is the same as non-UTF-8 because + // the protocol buffer contains no UTF-8 text. + EXPECT_EQ(correct_string, utf8_debug_string); string expected_short_debug_string = "optional_string: " + kEscapeTestStringEscaped; EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString()); } +TEST_F(TextFormatTest, Utf8DebugString) { + // Set the string value to test. + proto_.set_optional_string("\350\260\267\346\255\214"); + + // Get the DebugString from the proto. + string debug_string = proto_.DebugString(); + string utf8_debug_string = proto_.Utf8DebugString(); + + // Hardcode a correct value to test against. + string correct_utf8_string = "optional_string: " + "\"\350\260\267\346\255\214\"" + "\n"; + string correct_string = "optional_string: " + "\"\\350\\260\\267\\346\\255\\214\"" + "\n"; + + // Compare. + EXPECT_EQ(correct_utf8_string, utf8_debug_string); + EXPECT_EQ(correct_string, debug_string); +} + TEST_F(TextFormatTest, PrintUnknownFields) { // Test printing of unknown fields in a message. @@ -603,10 +668,15 @@ class TextFormatParserTest : public testing::Test { void ExpectFailure(const string& input, const string& message, int line, int col, Message* proto) { + ExpectMessage(input, message, line, col, proto, false); + } + + void ExpectMessage(const string& input, const string& message, int line, + int col, Message* proto, bool expected_result) { TextFormat::Parser parser; MockErrorCollector error_collector; parser.RecordErrorsTo(&error_collector); - EXPECT_FALSE(parser.ParseFromString(input, proto)); + EXPECT_EQ(parser.ParseFromString(input, proto), expected_result); EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n", error_collector.text_); } @@ -625,6 +695,10 @@ class TextFormatParserTest : public testing::Test { strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", line + 1, column + 1, message); } + + void AddWarning(int line, int column, const string& message) { + AddError(line, column, "WARNING:" + message); + } }; }; @@ -945,6 +1019,12 @@ TEST_F(TextFormatParserTest, FailsOnTokenizationError) { errors[0]); } +TEST_F(TextFormatParserTest, ParseDeprecatedField) { + unittest::TestDeprecatedFields message; + ExpectMessage("deprecated_int32: 42", + "WARNING:text format contains deprecated field " + "\"deprecated_int32\"", 1, 21, &message, true); +} class TextFormatMessageSetTest : public testing::Test { protected: @@ -991,5 +1071,4 @@ TEST_F(TextFormatMessageSetTest, Deserialize) { } // namespace text_format_unittest } // namespace protobuf - } // namespace google diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index 03811de..d51fa1e 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -155,6 +155,10 @@ message TestAllTypes { optional string default_cord = 85 [ctype=CORD,default="123"]; } +message TestDeprecatedFields { + optional int32 deprecated_int32 = 1 [deprecated=true]; +} + // Define these after TestAllTypes to make sure the compiler can handle // that. message ForeignMessage { @@ -348,6 +352,12 @@ message TestEmptyMessageWithExtensions { extensions 1 to max; } +message TestMultipleExtensionRanges { + extensions 42; + extensions 4143 to 4243; + extensions 65536 to max; +} + // Test that really large tag numbers don't break anything. message TestReallyLargeTagNumber { // The largest possible tag number is 2^28 - 1, since the wire format uses @@ -372,13 +382,14 @@ message TestMutualRecursionB { } // Test that groups have disjoint field numbers from their siblings and -// parents. This is NOT possible in proto1; only proto2. When outputting -// proto1, the dup fields should be dropped. -message TestDupFieldNumber { - optional int32 a = 1; - optional group Foo = 2 { optional int32 a = 1; } - optional group Bar = 3 { optional int32 a = 1; } -} +// parents. This is NOT possible in proto1; only proto2. When attempting +// to compile with proto1, this will emit an error; so we only include it +// in protobuf_unittest_proto. +message TestDupFieldNumber { // NO_PROTO1 + optional int32 a = 1; // NO_PROTO1 + optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1 + optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1 +} // NO_PROTO1 // Needed for a Python test. @@ -468,6 +479,14 @@ message TestExtremeDefaultValues { // Using exponents optional float large_float = 12 [default = 2E8]; optional float small_negative_float = 13 [default = -8e-28]; + + // Text for nonfinite floating-point values. + optional double inf_double = 14 [default = inf]; + optional double neg_inf_double = 15 [default = -inf]; + optional double nan_double = 16 [default = nan]; + optional float inf_float = 17 [default = inf]; + optional float neg_inf_float = 18 [default = -inf]; + optional float nan_float = 19 [default = nan]; } // Test String and Bytes: string is for valid UTF-8 strings @@ -498,6 +517,25 @@ message TestPackedTypes { repeated ForeignEnum packed_enum = 103 [packed = true]; } +// A message with the same fields as TestPackedTypes, but without packing. Used +// to test packed <-> unpacked wire compatibility. +message TestUnpackedTypes { + repeated int32 unpacked_int32 = 90 [packed = false]; + repeated int64 unpacked_int64 = 91 [packed = false]; + repeated uint32 unpacked_uint32 = 92 [packed = false]; + repeated uint64 unpacked_uint64 = 93 [packed = false]; + repeated sint32 unpacked_sint32 = 94 [packed = false]; + repeated sint64 unpacked_sint64 = 95 [packed = false]; + repeated fixed32 unpacked_fixed32 = 96 [packed = false]; + repeated fixed64 unpacked_fixed64 = 97 [packed = false]; + repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; + repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; + repeated float unpacked_float = 100 [packed = false]; + repeated double unpacked_double = 101 [packed = false]; + repeated bool unpacked_bool = 102 [packed = false]; + repeated ForeignEnum unpacked_enum = 103 [packed = false]; +} + message TestPackedExtensions { extensions 1 to max; } @@ -519,6 +557,47 @@ extend TestPackedExtensions { repeated ForeignEnum packed_enum_extension = 103 [packed = true]; } +// Used by ExtensionSetTest/DynamicExtensions. The test actually builds +// a set of extensions to TestAllExtensions dynamically, based on the fields +// of this message type. +message TestDynamicExtensions { + enum DynamicEnumType { + DYNAMIC_FOO = 2200; + DYNAMIC_BAR = 2201; + DYNAMIC_BAZ = 2202; + } + message DynamicMessageType { + optional int32 dynamic_field = 2100; + } + + optional fixed32 scalar_extension = 2000; + optional ForeignEnum enum_extension = 2001; + optional DynamicEnumType dynamic_enum_extension = 2002; + + optional ForeignMessage message_extension = 2003; + optional DynamicMessageType dynamic_message_extension = 2004; + + repeated string repeated_extension = 2005; + repeated sint32 packed_extension = 2006 [packed = true]; +} + +message TestRepeatedScalarDifferentTagSizes { + // Parsing repeated fixed size values used to fail. This message needs to be + // used in order to get a tag of the right size; all of the repeated fields + // in TestAllTypes didn't trigger the check. + repeated fixed32 repeated_fixed32 = 12; + // Check for a varint type, just for good measure. + repeated int32 repeated_int32 = 13; + + // These have two-byte tags. + repeated fixed64 repeated_fixed64 = 2046; + repeated int64 repeated_int64 = 2047; + + // Three byte tags. + repeated float repeated_float = 262142; + repeated uint64 repeated_uint64 = 262143; +} + // Test that RPC services work. message FooRequest {} message FooResponse {} diff --git a/src/google/protobuf/unittest_enormous_descriptor.proto b/src/google/protobuf/unittest_enormous_descriptor.proto index 6ad2dab..bc0b7c1 100644 --- a/src/google/protobuf/unittest_enormous_descriptor.proto +++ b/src/google/protobuf/unittest_enormous_descriptor.proto @@ -35,6 +35,7 @@ // A proto file that has an extremely large descriptor. Used to test that // descriptors over 64k don't break the string literal length limit in Java. + package google.protobuf; option java_package = "com.google.protobuf"; diff --git a/src/google/protobuf/unittest_micro.proto b/src/google/protobuf/unittest_micro.proto deleted file mode 100644 index 3d7fcd2..0000000 --- a/src/google/protobuf/unittest_micro.proto +++ /dev/null @@ -1,162 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: wink@google.com (Wink Saville) - -package protobuf_unittest; - -import "google/protobuf/unittest_import_micro.proto"; - -option java_package = "com.google.protobuf.micro"; -option java_outer_classname = "MicroOuterClass"; - -// Same as TestAllTypes but with the micro runtime. -message TestAllTypesMicro { - - message NestedMessage { - optional int32 bb = 1; - } - - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - } - - // Singular - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional NestedMessage optional_nested_message = 18; - optional ForeignMessageMicro optional_foreign_message = 19; - optional protobuf_unittest_import.ImportMessageMicro - optional_import_message = 20; - - optional NestedEnum optional_nested_enum = 21; - optional ForeignEnumMicro optional_foreign_enum = 22; - optional protobuf_unittest_import.ImportEnumMicro optional_import_enum = 23; - - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessageMicro repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessageMicro - repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnumMicro repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnumMicro repeated_import_enum = 53; - - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; - - // Singular with defaults - optional int32 default_int32 = 61 [default = 41 ]; - optional int64 default_int64 = 62 [default = 42 ]; - optional uint32 default_uint32 = 63 [default = 43 ]; - optional uint64 default_uint64 = 64 [default = 44 ]; - optional sint32 default_sint32 = 65 [default = -45 ]; - optional sint64 default_sint64 = 66 [default = 46 ]; - optional fixed32 default_fixed32 = 67 [default = 47 ]; - optional fixed64 default_fixed64 = 68 [default = 48 ]; - optional sfixed32 default_sfixed32 = 69 [default = 49 ]; - optional sfixed64 default_sfixed64 = 70 [default = -50 ]; - optional float default_float = 71 [default = 51.5 ]; - optional double default_double = 72 [default = 52e3 ]; - optional bool default_bool = 73 [default = true ]; - optional string default_string = 74 [default = "hello"]; - optional bytes default_bytes = 75 [default = "world"]; - - optional NestedEnum default_nested_enum = 81 [default = BAR]; - optional ForeignEnumMicro default_foreign_enum = 82 - [default = FOREIGN_MICRO_BAR]; - optional protobuf_unittest_import.ImportEnumMicro - default_import_enum = 83 [default = IMPORT_MICRO_BAR]; - - optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; - optional string default_cord = 85 [ctype=CORD,default="123"]; - - required int32 id = 86; -} - -message ForeignMessageMicro { - optional int32 c = 1; -} - -enum ForeignEnumMicro { - FOREIGN_MICRO_FOO = 4; - FOREIGN_MICRO_BAR = 5; - FOREIGN_MICRO_BAZ = 6; -} - -// Test that deprecated fields work. We only verify that they compile (at one -// point this failed). -message TestDeprecatedMicro { - optional int32 deprecated_field = 1 [deprecated = true]; -} diff --git a/src/google/protobuf/unittest_import_micro.proto b/src/google/protobuf/unittest_no_generic_services.proto index adac807..fcae421 100644 --- a/src/google/protobuf/unittest_import_micro.proto +++ b/src/google/protobuf/unittest_no_generic_services.proto @@ -29,21 +29,26 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) -// -// This is like unittest_import.proto but with optimize_for = MICRO_RUNTIME. -package protobuf_unittest_import; +package google.protobuf.no_generic_services_test; + +option cc_generic_services = false; +option java_generic_services = false; +option py_generic_services = false; -// java_package and java_outer_classname are specified on the command line. -//option java_package = "com.google.protobuf.micro"; -//option java_outer_classname = "UnittestImportMicro"; +message TestMessage { + optional int32 a = 1; + extensions 1000 to max; +} + +enum TestEnum { + FOO = 1; +} -message ImportMessageMicro { - optional int32 d = 1; +extend TestMessage { + optional int32 test_extension = 1000; } -enum ImportEnumMicro { - IMPORT_MICRO_FOO = 7; - IMPORT_MICRO_BAR = 8; - IMPORT_MICRO_BAZ = 9; +service TestService { + rpc Foo(TestMessage) returns(TestMessage); } diff --git a/src/google/protobuf/unittest_stringutf8_micro.proto b/src/google/protobuf/unittest_stringutf8_micro.proto deleted file mode 100644 index e4bbe3d..0000000 --- a/src/google/protobuf/unittest_stringutf8_micro.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: wink@google.com (Wink Saville) -// - -package protobuf_unittest_import; - -option java_package = "com.google.protobuf.micro"; - -message StringUtf8 { - optional string id = 1; - repeated string rs = 2; -} diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index 318ffaf..e1f8b83 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc @@ -32,6 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/stubs/common.h> #include <google/protobuf/unknown_field_set.h> #include <google/protobuf/stubs/stl_util-inl.h> #include <google/protobuf/io/coded_stream.h> @@ -50,13 +51,12 @@ UnknownFieldSet::~UnknownFieldSet() { delete fields_; } -void UnknownFieldSet::Clear() { - if (fields_ != NULL) { - for (int i = 0; i < fields_->size(); i++) { - (*fields_)[i].Delete(); - } - fields_->clear(); +void UnknownFieldSet::ClearFallback() { + GOOGLE_DCHECK(fields_ != NULL); + for (int i = 0; i < fields_->size(); i++) { + (*fields_)[i].Delete(); } + fields_->clear(); } void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h index d6ca70f..84c2e2b 100644 --- a/src/google/protobuf/unknown_field_set.h +++ b/src/google/protobuf/unknown_field_set.h @@ -66,7 +66,7 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet { ~UnknownFieldSet(); // Remove all fields. - void Clear(); + inline void Clear(); // Is this set empty? inline bool empty() const; @@ -119,6 +119,8 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet { } private: + void ClearFallback(); + vector<UnknownField>* fields_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet); @@ -180,6 +182,12 @@ class LIBPROTOBUF_EXPORT UnknownField { // =================================================================== // inline implementations +inline void UnknownFieldSet::Clear() { + if (fields_ != NULL) { + ClearFallback(); + } +} + inline bool UnknownFieldSet::empty() const { return fields_ == NULL || fields_->empty(); } diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index 5aa6772..831a579 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -391,7 +391,12 @@ bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, // If that failed, check if the field is an extension. if (field == NULL && descriptor->IsExtensionNumber(field_number)) { - field = message_reflection->FindKnownExtensionByNumber(field_number); + if (input->GetExtensionPool() == NULL) { + field = message_reflection->FindKnownExtensionByNumber(field_number); + } else { + field = input->GetExtensionPool() + ->FindExtensionByNumber(descriptor, field_number); + } } // If that failed, but we're a MessageSet, and this is the tag for a @@ -419,52 +424,67 @@ bool WireFormat::ParseAndMergeField( io::CodedInputStream* input) { const Reflection* message_reflection = message->GetReflection(); - if (field == NULL || - WireFormatLite::GetTagWireType(tag) != WireTypeForField(field)) { - // We don't recognize this field. Either the field number is unknown - // or the wire type doesn't match. Put it in our unknown field set. - return SkipField(input, tag, - message_reflection->MutableUnknownFields(message)); + enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format; + + if (field == NULL) { + value_format = UNKNOWN; + } else if (WireFormatLite::GetTagWireType(tag) == + WireTypeForFieldType(field->type())) { + value_format = NORMAL_FORMAT; + } else if (field->is_packable() && + WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + value_format = PACKED_FORMAT; + } else { + // We don't recognize this field. Either the field number is unknown + // or the wire type doesn't match. Put it in our unknown field set. + value_format = UNKNOWN; } - if (field->options().packed()) { + if (value_format == UNKNOWN) { + return SkipField(input, tag, + message_reflection->MutableUnknownFields(message)); + } else if (value_format == PACKED_FORMAT) { uint32 length; if (!input->ReadVarint32(&length)) return false; io::CodedInputStream::Limit limit = input->PushLimit(length); switch (field->type()) { -#define HANDLE_PACKED_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \ +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: { \ while (input->BytesUntilLimit() > 0) { \ CPPTYPE value; \ - if (!WireFormatLite::Read##TYPE_METHOD(input, &value)) return false; \ + if (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \ + return false; \ message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ } \ break; \ } - HANDLE_PACKED_TYPE( INT32, Int32, int32, Int32) - HANDLE_PACKED_TYPE( INT64, Int64, int64, Int64) - HANDLE_PACKED_TYPE(SINT32, SInt32, int32, Int32) - HANDLE_PACKED_TYPE(SINT64, SInt64, int64, Int64) - HANDLE_PACKED_TYPE(UINT32, UInt32, uint32, UInt32) - HANDLE_PACKED_TYPE(UINT64, UInt64, uint64, UInt64) + HANDLE_PACKED_TYPE( INT32, int32, Int32) + HANDLE_PACKED_TYPE( INT64, int64, Int64) + HANDLE_PACKED_TYPE(SINT32, int32, Int32) + HANDLE_PACKED_TYPE(SINT64, int64, Int64) + HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) + HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) - HANDLE_PACKED_TYPE( FIXED32, Fixed32, uint32, UInt32) - HANDLE_PACKED_TYPE( FIXED64, Fixed64, uint64, UInt64) - HANDLE_PACKED_TYPE(SFIXED32, SFixed32, int32, Int32) - HANDLE_PACKED_TYPE(SFIXED64, SFixed64, int64, Int64) + HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32) + HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64) + HANDLE_PACKED_TYPE(SFIXED32, int32, Int32) + HANDLE_PACKED_TYPE(SFIXED64, int64, Int64) - HANDLE_PACKED_TYPE(FLOAT , Float , float , Float ) - HANDLE_PACKED_TYPE(DOUBLE, Double, double, Double) + HANDLE_PACKED_TYPE(FLOAT , float , Float ) + HANDLE_PACKED_TYPE(DOUBLE, double, Double) - HANDLE_PACKED_TYPE(BOOL, Bool, bool, Bool) + HANDLE_PACKED_TYPE(BOOL, bool, Bool) #undef HANDLE_PACKED_TYPE case FieldDescriptor::TYPE_ENUM: { while (input->BytesUntilLimit() > 0) { int value; - if (!WireFormatLite::ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) return false; const EnumValueDescriptor* enum_value = field->enum_type()->FindValueByNumber(value); if (enum_value != NULL) { @@ -487,11 +507,14 @@ bool WireFormat::ParseAndMergeField( input->PopLimit(limit); } else { + // Non-packed value (value_format == NORMAL_FORMAT) switch (field->type()) { -#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \ +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: { \ CPPTYPE value; \ - if (!WireFormatLite::Read##TYPE_METHOD(input, &value)) return false; \ + if (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \ + return false; \ if (field->is_repeated()) { \ message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ } else { \ @@ -500,31 +523,28 @@ bool WireFormat::ParseAndMergeField( break; \ } - HANDLE_TYPE( INT32, Int32, int32, Int32) - HANDLE_TYPE( INT64, Int64, int64, Int64) - HANDLE_TYPE(SINT32, SInt32, int32, Int32) - HANDLE_TYPE(SINT64, SInt64, int64, Int64) - HANDLE_TYPE(UINT32, UInt32, uint32, UInt32) - HANDLE_TYPE(UINT64, UInt64, uint64, UInt64) - - HANDLE_TYPE( FIXED32, Fixed32, uint32, UInt32) - HANDLE_TYPE( FIXED64, Fixed64, uint64, UInt64) - HANDLE_TYPE(SFIXED32, SFixed32, int32, Int32) - HANDLE_TYPE(SFIXED64, SFixed64, int64, Int64) - - HANDLE_TYPE(FLOAT , Float , float , Float ) - HANDLE_TYPE(DOUBLE, Double, double, Double) + HANDLE_TYPE( INT32, int32, Int32) + HANDLE_TYPE( INT64, int64, Int64) + HANDLE_TYPE(SINT32, int32, Int32) + HANDLE_TYPE(SINT64, int64, Int64) + HANDLE_TYPE(UINT32, uint32, UInt32) + HANDLE_TYPE(UINT64, uint64, UInt64) - HANDLE_TYPE(BOOL, Bool, bool, Bool) + HANDLE_TYPE( FIXED32, uint32, UInt32) + HANDLE_TYPE( FIXED64, uint64, UInt64) + HANDLE_TYPE(SFIXED32, int32, Int32) + HANDLE_TYPE(SFIXED64, int64, Int64) - HANDLE_TYPE(STRING, String, string, String) - HANDLE_TYPE(BYTES, Bytes, string, String) + HANDLE_TYPE(FLOAT , float , Float ) + HANDLE_TYPE(DOUBLE, double, Double) + HANDLE_TYPE(BOOL, bool, Bool) #undef HANDLE_TYPE case FieldDescriptor::TYPE_ENUM: { int value; - if (!WireFormatLite::ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + input, &value)) return false; const EnumValueDescriptor* enum_value = field->enum_type()->FindValueByNumber(value); if (enum_value != NULL) { @@ -544,13 +564,38 @@ bool WireFormat::ParseAndMergeField( break; } + // Handle strings separately so that we can optimize the ctype=CORD case. + case FieldDescriptor::TYPE_STRING: { + string value; + if (!WireFormatLite::ReadString(input, &value)) return false; + VerifyUTF8String(value.data(), value.length(), PARSE); + if (field->is_repeated()) { + message_reflection->AddString(message, field, value); + } else { + message_reflection->SetString(message, field, value); + } + break; + } + + case FieldDescriptor::TYPE_BYTES: { + string value; + if (!WireFormatLite::ReadBytes(input, &value)) return false; + if (field->is_repeated()) { + message_reflection->AddString(message, field, value); + } else { + message_reflection->SetString(message, field, value); + } + break; + } case FieldDescriptor::TYPE_GROUP: { Message* sub_message; if (field->is_repeated()) { - sub_message = message_reflection->AddMessage(message, field); + sub_message = message_reflection->AddMessage( + message, field, input->GetExtensionFactory()); } else { - sub_message = message_reflection->MutableMessage(message, field); + sub_message = message_reflection->MutableMessage( + message, field, input->GetExtensionFactory()); } if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag), @@ -562,9 +607,11 @@ bool WireFormat::ParseAndMergeField( case FieldDescriptor::TYPE_MESSAGE: { Message* sub_message; if (field->is_repeated()) { - sub_message = message_reflection->AddMessage(message, field); + sub_message = message_reflection->AddMessage( + message, field, input->GetExtensionFactory()); } else { - sub_message = message_reflection->MutableMessage(message, field); + sub_message = message_reflection->MutableMessage( + message, field, input->GetExtensionFactory()); } if (!WireFormatLite::ReadMessage(input, sub_message)) return false; @@ -782,23 +829,23 @@ void WireFormat::SerializeFieldWithCachedSizes( // Handle strings separately so that we can get string references // instead of copying. case FieldDescriptor::TYPE_STRING: { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - VerifyUTF8String(value.data(), value.length(), SERIALIZE); - WireFormatLite::WriteString(field->number(), value, output); + string scratch; + const string& value = field->is_repeated() ? + message_reflection->GetRepeatedStringReference( + message, field, j, &scratch) : + message_reflection->GetStringReference(message, field, &scratch); + VerifyUTF8String(value.data(), value.length(), SERIALIZE); + WireFormatLite::WriteString(field->number(), value, output); break; } case FieldDescriptor::TYPE_BYTES: { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - WireFormatLite::WriteBytes(field->number(), value, output); + string scratch; + const string& value = field->is_repeated() ? + message_reflection->GetRepeatedStringReference( + message, field, j, &scratch) : + message_reflection->GetStringReference(message, field, &scratch); + WireFormatLite::WriteBytes(field->number(), value, output); break; } } @@ -961,14 +1008,14 @@ int WireFormat::FieldDataOnlyByteSize( // instead of copying. case FieldDescriptor::TYPE_STRING: case FieldDescriptor::TYPE_BYTES: { - for (int j = 0; j < count; j++) { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - data_size += WireFormatLite::StringSize(value); - } + for (int j = 0; j < count; j++) { + string scratch; + const string& value = field->is_repeated() ? + message_reflection->GetRepeatedStringReference( + message, field, j, &scratch) : + message_reflection->GetStringReference(message, field, &scratch); + data_size += WireFormatLite::StringSize(value); + } break; } } diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index 5d09803..d347d11 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc @@ -32,14 +32,13 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/wire_format_lite_inl.h> + #include <stack> #include <string> #include <vector> - -#include <google/protobuf/wire_format_lite_inl.h> - #include <google/protobuf/stubs/common.h> -#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/coded_stream_inl.h> #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> @@ -187,6 +186,174 @@ void FieldSkipper::SkipUnknownEnum( // Nothing. } +bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input, + bool (*is_valid)(int), + RepeatedField<int>* values) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + if (!google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, WireFormatLite::TYPE_ENUM>(input, &value)) { + return false; + } + if (is_valid(value)) { + values->Add(value); + } + } + input->PopLimit(limit); + return true; +} + +void WireFormatLite::WriteInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt32NoTag(value, output); +} +void WireFormatLite::WriteInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteInt64NoTag(value, output); +} +void WireFormatLite::WriteUInt32(int field_number, uint32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt32NoTag(value, output); +} +void WireFormatLite::WriteUInt64(int field_number, uint64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteUInt64NoTag(value, output); +} +void WireFormatLite::WriteSInt32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt32NoTag(value, output); +} +void WireFormatLite::WriteSInt64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteSInt64NoTag(value, output); +} +void WireFormatLite::WriteFixed32(int field_number, uint32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFixed32NoTag(value, output); +} +void WireFormatLite::WriteFixed64(int field_number, uint64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteFixed64NoTag(value, output); +} +void WireFormatLite::WriteSFixed32(int field_number, int32 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteSFixed32NoTag(value, output); +} +void WireFormatLite::WriteSFixed64(int field_number, int64 value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteSFixed64NoTag(value, output); +} +void WireFormatLite::WriteFloat(int field_number, float value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED32, output); + WriteFloatNoTag(value, output); +} +void WireFormatLite::WriteDouble(int field_number, double value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_FIXED64, output); + WriteDoubleNoTag(value, output); +} +void WireFormatLite::WriteBool(int field_number, bool value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteBoolNoTag(value, output); +} +void WireFormatLite::WriteEnum(int field_number, int value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_VARINT, output); + WriteEnumNoTag(value, output); +} + +void WireFormatLite::WriteString(int field_number, const string& value, + io::CodedOutputStream* output) { + // String is for UTF-8 text only + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(value.size()); + output->WriteString(value); +} +void WireFormatLite::WriteBytes(int field_number, const string& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(value.size()); + output->WriteString(value); +} + + +void WireFormatLite::WriteGroup(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} + +void WireFormatLite::WriteMessage(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + const int size = value.GetCachedSize(); + output->WriteVarint32(size); + value.SerializeWithCachedSizes(output); +} + +void WireFormatLite::WriteGroupMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + const int size = value.GetCachedSize(); + uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); + if (target != NULL) { + uint8* end = value.SerializeWithCachedSizesToArray(target); + GOOGLE_DCHECK_EQ(end - target, size); + } else { + value.SerializeWithCachedSizes(output); + } + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} + +void WireFormatLite::WriteMessageMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + const int size = value.GetCachedSize(); + output->WriteVarint32(size); + uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); + if (target != NULL) { + uint8* end = value.SerializeWithCachedSizesToArray(target); + GOOGLE_DCHECK_EQ(end - target, size); + } else { + value.SerializeWithCachedSizes(output); + } +} + +bool WireFormatLite::ReadString(io::CodedInputStream* input, + string* value) { + // String is for UTF-8 text only + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->InternalReadStringInline(value, length)) return false; + return true; +} +bool WireFormatLite::ReadBytes(io::CodedInputStream* input, + string* value) { + uint32 length; + if (!input->ReadVarint32(&length)) return false; + return input->InternalReadStringInline(value, length); +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index 9b7a401..e3d5b2d 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -46,15 +46,18 @@ namespace google { namespace protobuf { + template <typename T> class RepeatedField; // repeated_field.h namespace io { - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h } } namespace protobuf { namespace internal { +class StringPieceField; + // This class is for internal use by the protocol buffer library and by // protocol-complier-generated message classes. It must not be called // directly by clients. @@ -183,14 +186,21 @@ class LIBPROTOBUF_EXPORT WireFormatLite { // required string message = 3; // } // } + static const int kMessageSetItemNumber = 1; + static const int kMessageSetTypeIdNumber = 2; + static const int kMessageSetMessageNumber = 3; static const int kMessageSetItemStartTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormatLite::WIRETYPE_START_GROUP); + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, + WireFormatLite::WIRETYPE_START_GROUP); static const int kMessageSetItemEndTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormatLite::WIRETYPE_END_GROUP); + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, + WireFormatLite::WIRETYPE_END_GROUP); static const int kMessageSetTypeIdTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(2, WireFormatLite::WIRETYPE_VARINT); + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber, + WireFormatLite::WIRETYPE_VARINT); static const int kMessageSetMessageTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(3, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); // Byte size of all tags of a MessageSet::Item combined. static const int kMessageSetItemTagsSize; @@ -227,23 +237,59 @@ class LIBPROTOBUF_EXPORT WireFormatLite { // Read fields, not including tags. The assumption is that you already // read the tag to determine what field to read. - static inline bool ReadInt32 (input, int32* value); - static inline bool ReadInt64 (input, int64* value); - static inline bool ReadUInt32 (input, uint32* value); - static inline bool ReadUInt64 (input, uint64* value); - static inline bool ReadSInt32 (input, int32* value); - static inline bool ReadSInt64 (input, int64* value); - static inline bool ReadFixed32 (input, uint32* value); - static inline bool ReadFixed64 (input, uint64* value); - static inline bool ReadSFixed32(input, int32* value); - static inline bool ReadSFixed64(input, int64* value); - static inline bool ReadFloat (input, float* value); - static inline bool ReadDouble (input, double* value); - static inline bool ReadBool (input, bool* value); - static inline bool ReadEnum (input, int* value); - - static inline bool ReadString(input, string* value); - static inline bool ReadBytes (input, string* value); + + // For primitive fields, we just use a templatized routine parameterized by + // the represented type and the FieldType. These are specialized with the + // appropriate definition for each declared type. + template <typename CType, enum FieldType DeclaredType> + static inline bool ReadPrimitive(input, CType* value) INL; + + // Reads repeated primitive values, with optimizations for repeats. + // tag_size and tag should both be compile-time constants provided by the + // protocol compiler. + template <typename CType, enum FieldType DeclaredType> + static inline bool ReadRepeatedPrimitive(int tag_size, + uint32 tag, + input, + RepeatedField<CType>* value) INL; + + // Identical to ReadRepeatedPrimitive, except will not inline the + // implementation. + template <typename CType, enum FieldType DeclaredType> + static bool ReadRepeatedPrimitiveNoInline(int tag_size, + uint32 tag, + input, + RepeatedField<CType>* value); + + // Reads a primitive value directly from the provided buffer. It returns a + // pointer past the segment of data that was read. + // + // This is only implemented for the types with fixed wire size, e.g. + // float, double, and the (s)fixed* types. + template <typename CType, enum FieldType DeclaredType> + static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer, + CType* value) INL; + + // Reads a primitive packed field. + // + // This is only implemented for packable types. + template <typename CType, enum FieldType DeclaredType> + static inline bool ReadPackedPrimitive(input, + RepeatedField<CType>* value) INL; + + // Identical to ReadPackedPrimitive, except will not inline the + // implementation. + template <typename CType, enum FieldType DeclaredType> + static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value); + + // Read a packed enum field. Values for which is_valid() returns false are + // dropped. + static bool ReadPackedEnumNoInline(input, + bool (*is_valid)(int), + RepeatedField<int>* value); + + static bool ReadString(input, string* value); + static bool ReadBytes (input, string* value); static inline bool ReadGroup (field_number, input, MessageLite* value); static inline bool ReadMessage(input, MessageLite* value); @@ -279,38 +325,44 @@ class LIBPROTOBUF_EXPORT WireFormatLite { static inline void WriteEnumNoTag (int value, output) INL; // Write fields, including tags. - static inline void WriteInt32 (field_number, int32 value, output) INL; - static inline void WriteInt64 (field_number, int64 value, output) INL; - static inline void WriteUInt32 (field_number, uint32 value, output) INL; - static inline void WriteUInt64 (field_number, uint64 value, output) INL; - static inline void WriteSInt32 (field_number, int32 value, output) INL; - static inline void WriteSInt64 (field_number, int64 value, output) INL; - static inline void WriteFixed32 (field_number, uint32 value, output) INL; - static inline void WriteFixed64 (field_number, uint64 value, output) INL; - static inline void WriteSFixed32(field_number, int32 value, output) INL; - static inline void WriteSFixed64(field_number, int64 value, output) INL; - static inline void WriteFloat (field_number, float value, output) INL; - static inline void WriteDouble (field_number, double value, output) INL; - static inline void WriteBool (field_number, bool value, output) INL; - static inline void WriteEnum (field_number, int value, output) INL; - - static inline void WriteString(field_number, const string& value, output) INL; - static inline void WriteBytes (field_number, const string& value, output) INL; - - static inline void WriteGroup( - field_number, const MessageLite& value, output) INL; - static inline void WriteMessage( - field_number, const MessageLite& value, output) INL; + static void WriteInt32 (field_number, int32 value, output); + static void WriteInt64 (field_number, int64 value, output); + static void WriteUInt32 (field_number, uint32 value, output); + static void WriteUInt64 (field_number, uint64 value, output); + static void WriteSInt32 (field_number, int32 value, output); + static void WriteSInt64 (field_number, int64 value, output); + static void WriteFixed32 (field_number, uint32 value, output); + static void WriteFixed64 (field_number, uint64 value, output); + static void WriteSFixed32(field_number, int32 value, output); + static void WriteSFixed64(field_number, int64 value, output); + static void WriteFloat (field_number, float value, output); + static void WriteDouble (field_number, double value, output); + static void WriteBool (field_number, bool value, output); + static void WriteEnum (field_number, int value, output); + + static void WriteString(field_number, const string& value, output); + static void WriteBytes (field_number, const string& value, output); + + static void WriteGroup( + field_number, const MessageLite& value, output); + static void WriteMessage( + field_number, const MessageLite& value, output); + // Like above, but these will check if the output stream has enough + // space to write directly to a flat array. + static void WriteGroupMaybeToArray( + field_number, const MessageLite& value, output); + static void WriteMessageMaybeToArray( + field_number, const MessageLite& value, output); // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The // pointer must point at an instance of MessageType, *not* a subclass (or // the subclass must not override SerializeWithCachedSizes()). template<typename MessageType> static inline void WriteGroupNoVirtual( - field_number, const MessageType& value, output) INL; + field_number, const MessageType& value, output); template<typename MessageType> static inline void WriteMessageNoVirtual( - field_number, const MessageType& value, output) INL; + field_number, const MessageType& value, output); #undef output #define output uint8* target @@ -426,6 +478,16 @@ class LIBPROTOBUF_EXPORT WireFormatLite { static inline int MessageSizeNoVirtual(const MessageType& value); private: + // A helper method for the repeated primitive reader. This method has + // optimizations for primitive types that have fixed size on the wire, and + // can be read using potentially faster paths. + template <typename CType, enum FieldType DeclaredType> + static inline bool ReadRepeatedFixedSizePrimitive( + int tag_size, + uint32 tag, + google::protobuf::io::CodedInputStream* input, + RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + static const CppType kFieldTypeToCppTypeMap[]; static const WireFormatLite::WireType kWireTypeForFieldType[]; diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h index eb9155e..d7b2c30 100644 --- a/src/google/protobuf/wire_format_lite_inl.h +++ b/src/google/protobuf/wire_format_lite_inl.h @@ -39,7 +39,9 @@ #include <string> #include <google/protobuf/stubs/common.h> #include <google/protobuf/message_lite.h> +#include <google/protobuf/repeated_field.h> #include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/generated_message_util.h> #include <google/protobuf/io/coded_stream.h> @@ -47,106 +49,295 @@ namespace google { namespace protobuf { namespace internal { -inline bool WireFormatLite::ReadInt32(io::CodedInputStream* input, - int32* value) { +// Implementation details of ReadPrimitive. + +template <> +inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>( + io::CodedInputStream* input, + int32* value) { uint32 temp; if (!input->ReadVarint32(&temp)) return false; *value = static_cast<int32>(temp); return true; } -inline bool WireFormatLite::ReadInt64(io::CodedInputStream* input, - int64* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>( + io::CodedInputStream* input, + int64* value) { uint64 temp; if (!input->ReadVarint64(&temp)) return false; *value = static_cast<int64>(temp); return true; } -inline bool WireFormatLite::ReadUInt32(io::CodedInputStream* input, - uint32* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>( + io::CodedInputStream* input, + uint32* value) { return input->ReadVarint32(value); } -inline bool WireFormatLite::ReadUInt64(io::CodedInputStream* input, - uint64* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>( + io::CodedInputStream* input, + uint64* value) { return input->ReadVarint64(value); } -inline bool WireFormatLite::ReadSInt32(io::CodedInputStream* input, - int32* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>( + io::CodedInputStream* input, + int32* value) { uint32 temp; if (!input->ReadVarint32(&temp)) return false; *value = ZigZagDecode32(temp); return true; } -inline bool WireFormatLite::ReadSInt64(io::CodedInputStream* input, - int64* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>( + io::CodedInputStream* input, + int64* value) { uint64 temp; if (!input->ReadVarint64(&temp)) return false; *value = ZigZagDecode64(temp); return true; } -inline bool WireFormatLite::ReadFixed32(io::CodedInputStream* input, - uint32* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>( + io::CodedInputStream* input, + uint32* value) { return input->ReadLittleEndian32(value); } -inline bool WireFormatLite::ReadFixed64(io::CodedInputStream* input, - uint64* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>( + io::CodedInputStream* input, + uint64* value) { return input->ReadLittleEndian64(value); } -inline bool WireFormatLite::ReadSFixed32(io::CodedInputStream* input, - int32* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>( + io::CodedInputStream* input, + int32* value) { uint32 temp; if (!input->ReadLittleEndian32(&temp)) return false; *value = static_cast<int32>(temp); return true; } -inline bool WireFormatLite::ReadSFixed64(io::CodedInputStream* input, - int64* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>( + io::CodedInputStream* input, + int64* value) { uint64 temp; if (!input->ReadLittleEndian64(&temp)) return false; *value = static_cast<int64>(temp); return true; } -inline bool WireFormatLite::ReadFloat(io::CodedInputStream* input, - float* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>( + io::CodedInputStream* input, + float* value) { uint32 temp; if (!input->ReadLittleEndian32(&temp)) return false; *value = DecodeFloat(temp); return true; } -inline bool WireFormatLite::ReadDouble(io::CodedInputStream* input, - double* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>( + io::CodedInputStream* input, + double* value) { uint64 temp; if (!input->ReadLittleEndian64(&temp)) return false; *value = DecodeDouble(temp); return true; } -inline bool WireFormatLite::ReadBool(io::CodedInputStream* input, - bool* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( + io::CodedInputStream* input, + bool* value) { uint32 temp; if (!input->ReadVarint32(&temp)) return false; *value = temp != 0; return true; } -inline bool WireFormatLite::ReadEnum(io::CodedInputStream* input, - int* value) { +template <> +inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( + io::CodedInputStream* input, + int* value) { uint32 temp; if (!input->ReadVarint32(&temp)) return false; *value = static_cast<int>(temp); return true; } -inline bool WireFormatLite::ReadString(io::CodedInputStream* input, - string* value) { - // String is for UTF-8 text only - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->ReadString(value, length)) return false; +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + uint32, WireFormatLite::TYPE_FIXED32>( + const uint8* buffer, + uint32* value) { + return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + uint64, WireFormatLite::TYPE_FIXED64>( + const uint8* buffer, + uint64* value) { + return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + int32, WireFormatLite::TYPE_SFIXED32>( + const uint8* buffer, + int32* value) { + uint32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = static_cast<int32>(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + int64, WireFormatLite::TYPE_SFIXED64>( + const uint8* buffer, + int64* value) { + uint64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = static_cast<int64>(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + float, WireFormatLite::TYPE_FLOAT>( + const uint8* buffer, + float* value) { + uint32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = DecodeFloat(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + double, WireFormatLite::TYPE_DOUBLE>( + const uint8* buffer, + double* value) { + uint64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = DecodeDouble(temp); + return buffer; +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +inline bool WireFormatLite::ReadRepeatedPrimitive(int tag_size, + uint32 tag, + io::CodedInputStream* input, + RepeatedField<CType>* values) { + CType value; + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->Add(value); + int elements_already_reserved = values->Capacity() - values->size(); + while (elements_already_reserved > 0 && input->ExpectTag(tag)) { + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->AddAlreadyReserved(value); + elements_already_reserved--; + } + return true; +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( + int tag_size, + uint32 tag, + io::CodedInputStream* input, + RepeatedField<CType>* values) { + GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size); + CType value; + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) + return false; + values->Add(value); + + // For fixed size values, repeated values can be read more quickly by + // reading directly from a raw array. + // + // We can get a tight loop by only reading as many elements as can be + // added to the RepeatedField without having to do any resizing. Additionally, + // we only try to read as many elements as are available from the current + // buffer space. Doing so avoids having to perform boundary checks when + // reading the value: the maximum number of elements that can be read is + // known outside of the loop. + const void* void_pointer; + int size; + input->GetDirectBufferPointerInline(&void_pointer, &size); + if (size > 0) { + const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer); + // The number of bytes each type occupies on the wire. + const int per_value_size = tag_size + sizeof(value); + + int elements_available = min(values->Capacity() - values->size(), + size / per_value_size); + int num_read = 0; + while (num_read < elements_available && + (buffer = io::CodedInputStream::ExpectTagFromArray( + buffer, tag)) != NULL) { + buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value); + values->AddAlreadyReserved(value); + ++num_read; + } + const int read_bytes = num_read * per_value_size; + if (read_bytes > 0) { + input->Skip(read_bytes); + } + } return true; } -inline bool WireFormatLite::ReadBytes(io::CodedInputStream* input, - string* value) { + +// Specializations of ReadRepeatedPrimitive for the fixed size types, which use +// the optimized code path. +#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ +template <> \ +inline bool WireFormatLite::ReadRepeatedPrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + int tag_size, \ + uint32 tag, \ + io::CodedInputStream* input, \ + RepeatedField<CPPTYPE>* values) { \ + return ReadRepeatedFixedSizePrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + tag_size, tag, input, values); \ +} + +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32); +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64); +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32); +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64); +READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT); +READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE); + +#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +bool WireFormatLite::ReadRepeatedPrimitiveNoInline( + int tag_size, + uint32 tag, + io::CodedInputStream* input, + RepeatedField<CType>* value) { + return ReadRepeatedPrimitive<CType, DeclaredType>( + tag_size, tag, input, value); +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, + RepeatedField<CType>* values) { uint32 length; if (!input->ReadVarint32(&length)) return false; - return input->ReadString(value, length); + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + CType value; + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; + values->Add(value); + } + input->PopLimit(limit); + return true; +} + +template <typename CType, enum WireFormatLite::FieldType DeclaredType> +bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, + RepeatedField<CType>* values) { + return ReadPackedPrimitive<CType, DeclaredType>(input, values); } @@ -270,107 +461,6 @@ inline void WireFormatLite::WriteEnumNoTag(int value, output->WriteVarint32SignExtended(value); } -inline void WireFormatLite::WriteInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteInt32NoTag(value, output); -} -inline void WireFormatLite::WriteInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteInt64NoTag(value, output); -} -inline void WireFormatLite::WriteUInt32(int field_number, uint32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteUInt32NoTag(value, output); -} -inline void WireFormatLite::WriteUInt64(int field_number, uint64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteUInt64NoTag(value, output); -} -inline void WireFormatLite::WriteSInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteSInt32NoTag(value, output); -} -inline void WireFormatLite::WriteSInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteSInt64NoTag(value, output); -} -inline void WireFormatLite::WriteFixed32(int field_number, uint32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteFixed32NoTag(value, output); -} -inline void WireFormatLite::WriteFixed64(int field_number, uint64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteFixed64NoTag(value, output); -} -inline void WireFormatLite::WriteSFixed32(int field_number, int32 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteSFixed32NoTag(value, output); -} -inline void WireFormatLite::WriteSFixed64(int field_number, int64 value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteSFixed64NoTag(value, output); -} -inline void WireFormatLite::WriteFloat(int field_number, float value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED32, output); - WriteFloatNoTag(value, output); -} -inline void WireFormatLite::WriteDouble(int field_number, double value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_FIXED64, output); - WriteDoubleNoTag(value, output); -} -inline void WireFormatLite::WriteBool(int field_number, bool value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteBoolNoTag(value, output); -} -inline void WireFormatLite::WriteEnum(int field_number, int value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_VARINT, output); - WriteEnumNoTag(value, output); -} - -inline void WireFormatLite::WriteString(int field_number, const string& value, - io::CodedOutputStream* output) { - // String is for UTF-8 text only - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.size()); - output->WriteString(value); -} -inline void WireFormatLite::WriteBytes(int field_number, const string& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.size()); - output->WriteString(value); -} - - -inline void WireFormatLite::WriteGroup(int field_number, - const MessageLite& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_START_GROUP, output); - value.SerializeWithCachedSizes(output); - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} -inline void WireFormatLite::WriteMessage(int field_number, - const MessageLite& value, - io::CodedOutputStream* output) { - WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.GetCachedSize()); - value.SerializeWithCachedSizes(output); -} - template<typename MessageType> inline void WireFormatLite::WriteGroupNoVirtual(int field_number, const MessageType& value, diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index 51960ee..867970c 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -126,6 +126,38 @@ TEST(WireFormatTest, ParsePacked) { TestUtil::ExpectPackedFieldsSet(dest); } +TEST(WireFormatTest, ParsePackedFromUnpacked) { + // Serialize using the generated code. + unittest::TestUnpackedTypes source; + TestUtil::SetUnpackedFields(&source); + string data = source.SerializeAsString(); + + // Parse using WireFormat. + unittest::TestPackedTypes dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectPackedFieldsSet(dest); +} + +TEST(WireFormatTest, ParseUnpackedFromPacked) { + // Serialize using the generated code. + unittest::TestPackedTypes source; + TestUtil::SetPackedFields(&source); + string data = source.SerializeAsString(); + + // Parse using WireFormat. + unittest::TestUnpackedTypes dest; + io::ArrayInputStream raw_input(data.data(), data.size()); + io::CodedInputStream input(&raw_input); + WireFormat::ParseAndMergePartial(&input, &dest); + + // Check. + TestUtil::ExpectUnpackedFieldsSet(dest); +} + TEST(WireFormatTest, ParsePackedExtensions) { unittest::TestPackedExtensions source, dest; string data; @@ -568,6 +600,45 @@ TEST(WireFormatTest, ZigZag) { LL(-75123905439571256)))); } +TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) { + // At one point checks would trigger when parsing repeated fixed scalar + // fields. + protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2; + for (int i = 0; i < 100; ++i) { + msg1.add_repeated_fixed32(i); + msg1.add_repeated_int32(i); + msg1.add_repeated_fixed64(i); + msg1.add_repeated_int64(i); + msg1.add_repeated_float(i); + msg1.add_repeated_uint64(i); + } + + // Make sure that we have a variety of tag sizes. + const google::protobuf::Descriptor* desc = msg1.GetDescriptor(); + const google::protobuf::FieldDescriptor* field; + field = desc->FindFieldByName("repeated_fixed32"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_int32"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_fixed64"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_int64"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_float"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); + field = desc->FindFieldByName("repeated_uint64"); + ASSERT_TRUE(field != NULL); + ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type())); + + EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString())); + EXPECT_EQ(msg1.DebugString(), msg2.DebugString()); +} + class WireFormatInvalidInputTest : public testing::Test { protected: // Make a serialized TestAllTypes in which the field optional_nested_message diff --git a/vsprojects/config.h b/vsprojects/config.h index e09f297..2c64450 100644 --- a/vsprojects/config.h +++ b/vsprojects/config.h @@ -5,7 +5,11 @@ #define HASH_MAP_H <hash_map> /* the namespace of hash_map/hash_set */ -#if _MSC_VER < 1310 +// Apparently Microsoft decided to move hash_map *back* to the std namespace +// in MSVC 2010: +// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx +// TODO(kenton): Use unordered_map instead, which is available in MSVC 2010. +#if _MSC_VER < 1310 || _MSC_VER >= 1600 #define HASH_NAMESPACE std #else #define HASH_NAMESPACE stdext diff --git a/vsprojects/libprotobuf-lite.vcproj b/vsprojects/libprotobuf-lite.vcproj index b373e75..8197699 100644 --- a/vsprojects/libprotobuf-lite.vcproj +++ b/vsprojects/libprotobuf-lite.vcproj @@ -1,270 +1,274 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="libprotobuf-lite"
- ProjectGUID="{49EA010D-706F-4BE2-A397-77854B72A040}"
- Keyword="Win32Proj"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- Optimization="0"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\src\google\protobuf\io\coded_stream.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\common.h"
- >
- </File>
- <File
- RelativePath=".\config.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\extension_set.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\generated_message_util.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\hash.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\map-util.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\message_lite.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\once.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\repeated_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\stl_util-inl.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format_lite.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format_lite_inl.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\src\google\protobuf\io\coded_stream.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\common.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\extension_set.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\generated_message_util.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\hash.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\message_lite.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\once.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\repeated_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format_lite.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="UTF-8"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="libprotobuf-lite" + ProjectGUID="{49EA010D-706F-4BE2-A397-77854B72A040}" + Keyword="Win32Proj" + TargetFrameworkVersion="0" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + Optimization="0" + AdditionalIncludeDirectories="../src;." + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + AdditionalIncludeDirectories="../src;." + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\src\google\protobuf\io\coded_stream.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\coded_stream_inl.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\common.h" + > + </File> + <File + RelativePath=".\config.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\extension_set.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\generated_message_util.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\hash.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\map-util.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\message_lite.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\once.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\repeated_field.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\stl_util-inl.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format_lite.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format_lite_inl.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\src\google\protobuf\io\coded_stream.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\common.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\extension_set.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\generated_message_util.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\hash.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\message_lite.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\once.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\repeated_field.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format_lite.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vsprojects/libprotobuf.vcproj b/vsprojects/libprotobuf.vcproj index df5b675..7b8111f 100644 --- a/vsprojects/libprotobuf.vcproj +++ b/vsprojects/libprotobuf.vcproj @@ -1,430 +1,434 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="libprotobuf"
- ProjectGUID="{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}"
- Keyword="Win32Proj"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- Optimization="0"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="4"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- AdditionalIncludeDirectories="../src;."
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\src\google\protobuf\io\coded_stream.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\common.h"
- >
- </File>
- <File
- RelativePath=".\config.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor.pb.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor_database.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\dynamic_message.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\extension_set.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\generated_message_reflection.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\generated_message_util.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\gzip_stream.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\hash.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\importer.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\map-util.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\message.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\message_lite.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\once.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\parser.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\printer.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\reflection_ops.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\repeated_field.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\service.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\stl_util-inl.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\strutil.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\substitute.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\text_format.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\tokenizer.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\unknown_field_set.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format_lite.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format_lite_inl.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\src\google\protobuf\io\coded_stream.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\common.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor.pb.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor_database.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\dynamic_message.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\extension_set.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\extension_set_heavy.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\generated_message_reflection.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\generated_message_util.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\gzip_stream.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\hash.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\importer.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\message.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\message_lite.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\once.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\parser.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\printer.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\reflection_ops.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\repeated_field.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\service.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\structurally_valid.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\strutil.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\substitute.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\text_format.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\tokenizer.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\unknown_field_set.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format_lite.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="UTF-8"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="libprotobuf" + ProjectGUID="{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}" + Keyword="Win32Proj" + TargetFrameworkVersion="0" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="4" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + Optimization="0" + AdditionalIncludeDirectories="../src;." + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="4" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + AdditionalIncludeDirectories="../src;." + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\src\google\protobuf\io\coded_stream.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\coded_stream_inl.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\common.h" + > + </File> + <File + RelativePath=".\config.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor.pb.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor_database.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\dynamic_message.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\extension_set.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\generated_message_reflection.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\generated_message_util.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\gzip_stream.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\hash.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\importer.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\map-util.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\message.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\message_lite.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\once.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\parser.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\printer.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\reflection_ops.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\repeated_field.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\service.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\stl_util-inl.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\strutil.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\substitute.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\text_format.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\tokenizer.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\unknown_field_set.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format_lite.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format_lite_inl.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\src\google\protobuf\io\coded_stream.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\common.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor.pb.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor_database.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\dynamic_message.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\extension_set.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\extension_set_heavy.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\generated_message_reflection.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\generated_message_util.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\gzip_stream.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\hash.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\importer.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\message.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\message_lite.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\once.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\parser.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\printer.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\reflection_ops.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\repeated_field.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\service.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\structurally_valid.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\strutil.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\substitute.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\text_format.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\tokenizer.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\unknown_field_set.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format_lite.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vsprojects/libprotoc.vcproj b/vsprojects/libprotoc.vcproj index abbb386..81063d3 100644 --- a/vsprojects/libprotoc.vcproj +++ b/vsprojects/libprotoc.vcproj @@ -156,6 +156,22 @@ >
</File>
<File
+ RelativePath="..\src\google\protobuf\compiler\subprocess.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\zip_writer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.pb.h"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.h"
>
</File>
@@ -272,6 +288,22 @@ >
</File>
<File
+ RelativePath="..\src\google\protobuf\compiler\subprocess.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\zip_writer.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\src\google\protobuf\compiler\plugin.pb.cc"
+ >
+ </File>
+ <File
RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.cc"
>
</File>
diff --git a/vsprojects/lite-test.vcproj b/vsprojects/lite-test.vcproj index be8e941..0887cf1 100644 --- a/vsprojects/lite-test.vcproj +++ b/vsprojects/lite-test.vcproj @@ -1,273 +1,273 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="lite-test"
- ProjectGUID="{12015ACE-42BE-4952-A5A0-44A9A46908E2}"
- RootNamespace="tests"
- Keyword="Win32Proj"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- Description=""
- CommandLine=""
- AdditionalDependencies=""
- Outputs=""
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- Optimization="0"
- AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- Description=""
- CommandLine=""
- AdditionalDependencies=""
- Outputs=""
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\src\google\protobuf\test_util_lite.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_lite.pb.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_import_lite.pb.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\src\google\protobuf\lite_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\test_util_lite.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_lite.pb.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_import_lite.pb.cc"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\src\google\protobuf\unittest_lite.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_lite.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto
"
- Outputs="google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_lite.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto
"
- Outputs="google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest_import_lite.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_import_lite.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto
"
- Outputs="google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_import_lite.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto
"
- Outputs="google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc"
- />
- </FileConfiguration>
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="UTF-8"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="lite-test" + ProjectGUID="{12015ACE-42BE-4952-A5A0-44A9A46908E2}" + RootNamespace="tests" + Keyword="Win32Proj" + TargetFrameworkVersion="0" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + AdditionalDependencies="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + Optimization="0" + AdditionalIncludeDirectories="../src;.;../gtest/include" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + AdditionalDependencies="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + AdditionalIncludeDirectories="../src;.;../gtest/include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\src\google\protobuf\test_util_lite.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_lite.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_import_lite.pb.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\src\google\protobuf\lite_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\test_util_lite.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_lite.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_import_lite.pb.cc" + > + </File> + </Filter> + <File + RelativePath="..\src\google\protobuf\unittest_lite.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_lite.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto
" + Outputs="google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_lite.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto
" + Outputs="google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_import_lite.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_import_lite.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto
" + Outputs="google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_import_lite.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto
" + Outputs="google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc" + /> + </FileConfiguration> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vsprojects/protobuf.sln b/vsprojects/protobuf.sln index d17546c..bac0055 100644 --- a/vsprojects/protobuf.sln +++ b/vsprojects/protobuf.sln @@ -20,6 +20,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcproj", "{4 {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
{3AF54C8A-10BF-4332-9147-F68ED9862032} = {3AF54C8A-10BF-4332-9147-F68ED9862032}
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} = {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}
{1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
EndProjectSection
EndProject
@@ -35,6 +36,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lite-test", "lite-test.vcpr {1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_plugin", "test_plugin.vcproj", "{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
+ {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+ {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -73,6 +81,10 @@ Global {12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.Build.0 = Debug|Win32
{12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.ActiveCfg = Release|Win32
{12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.Build.0 = Release|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.Build.0 = Debug|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.ActiveCfg = Release|Win32
+ {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/vsprojects/test_plugin.vcproj b/vsprojects/test_plugin.vcproj new file mode 100755 index 0000000..cfe387f --- /dev/null +++ b/vsprojects/test_plugin.vcproj @@ -0,0 +1,209 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="test_plugin"
+ ProjectGUID="{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
+ RootNamespace="test_plugin"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + AdditionalDependencies="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + Optimization="0" + AdditionalIncludeDirectories="../src;.;../gtest/include" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + AdditionalDependencies="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + AdditionalIncludeDirectories="../src;.;../gtest/include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + > + <File + RelativePath="..\src\google\protobuf\compiler\mock_code_generator.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\testing\file.h" + > + </File> + </Filter> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + > + <File + RelativePath="..\src\google\protobuf\compiler\test_plugin.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\mock_code_generator.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\testing\file.cc" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/vsprojects/tests.vcproj b/vsprojects/tests.vcproj index cd40b60..772046a 100644 --- a/vsprojects/tests.vcproj +++ b/vsprojects/tests.vcproj @@ -1,573 +1,625 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="tests"
- ProjectGUID="{4DF72760-C055-40A5-A77E-30A17E2AC2DB}"
- RootNamespace="tests"
- Keyword="Win32Proj"
- TargetFrameworkVersion="0"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- Description=""
- CommandLine=""
- AdditionalDependencies=""
- Outputs=""
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- Optimization="0"
- AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- Description=""
- CommandLine=""
- AdditionalDependencies=""
- Outputs=""
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
- AdditionalIncludeDirectories="../src;.;../gtest/include"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath=".\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\testing\file.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\testing\googletest.h"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\test_util.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest.pb.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_custom_options.pb.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_embed_optimize_for.pb.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_import.pb.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_lite_imports_nonline.pb.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_mset.pb.h"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_optimize_for.pb.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\src\google\protobuf\io\coded_stream_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\command_line_interface_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\common_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_bootstrap_unittest.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor_database_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\descriptor_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\dynamic_message_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\extension_set_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\testing\file.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\generated_message_reflection_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\testing\googletest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\importer_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\message_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\once_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\compiler\parser_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\printer_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\reflection_ops_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\repeated_field_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\structurally_valid_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\stubs\strutil_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\test_util.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\text_format_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\tokenizer_unittest.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest.pb.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_custom_options.pb.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_embed_optimize_for.pb.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_import.pb.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_lite_imports_nonlite.pb.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_mset.pb.cc"
- >
- </File>
- <File
- RelativePath=".\google\protobuf\unittest_optimize_for.pb.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\unknown_field_set_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\wire_format_unittest.cc"
- >
- </File>
- <File
- RelativePath="..\src\google\protobuf\io\zero_copy_stream_unittest.cc"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\src\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating cpp_test_bad_identifiers.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
"
- Outputs="google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating cpp_test_bad_identifiers.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
"
- Outputs="google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto
"
- Outputs="google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto
"
- Outputs="google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest_custom_options.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_custom_options.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto
"
- Outputs="google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_custom_options.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto
"
- Outputs="google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest_embed_optimize_for.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_embed_optimize_for.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto
"
- Outputs="google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_embed_optimize_for.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto
"
- Outputs="google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest_import.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_import.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto
"
- Outputs="google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_import.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto
"
- Outputs="google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest_lite_imports_nonlite.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_lite_imports_nonlite.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto
"
- Outputs="google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_lite_imports_nonlite.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto
"
- Outputs="google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest_mset.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_mset.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto
"
- Outputs="google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_mset.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto
"
- Outputs="google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\src\google\protobuf\unittest_optimize_for.proto"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_optimize_for.pb.{h,cc}..."
- CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto
"
- Outputs="google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCustomBuildTool"
- Description="Generating unittest_optimize_for.pb.{h,cc}..."
- CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto
"
- Outputs="google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc"
- />
- </FileConfiguration>
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="UTF-8"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="tests" + ProjectGUID="{4DF72760-C055-40A5-A77E-30A17E2AC2DB}" + RootNamespace="tests" + Keyword="Win32Proj" + TargetFrameworkVersion="0" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + AdditionalDependencies="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + Optimization="0" + AdditionalIncludeDirectories="../src;.;../gtest/include" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine="" + AdditionalDependencies="" + Outputs="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305" + AdditionalIncludeDirectories="../src;.;../gtest/include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\testing\file.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\testing\googletest.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\test_util.h" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\mock_code_generator.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_custom_options.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_embed_optimize_for.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_import.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_lite_imports_nonline.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_mset.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_optimize_for.pb.h" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_no_generic_services.pb.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\src\google\protobuf\io\coded_stream_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\command_line_interface_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\mock_code_generator.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\common_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\cpp\cpp_bootstrap_unittest.cc" + > + </File> + <File + RelativePath=".\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\cpp\cpp_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\cpp\cpp_plugin_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\java\java_plugin_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\python\python_plugin_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor_database_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\descriptor_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\dynamic_message_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\extension_set_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\testing\file.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\generated_message_reflection_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\testing\googletest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\importer_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\message_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\once_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\compiler\parser_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\printer_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\reflection_ops_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\repeated_field_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\structurally_valid_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\stubs\strutil_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\test_util.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\text_format_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\tokenizer_unittest.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_custom_options.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_embed_optimize_for.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_import.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_lite_imports_nonlite.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_mset.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_optimize_for.pb.cc" + > + </File> + <File + RelativePath=".\google\protobuf\unittest_no_generic_services.pb.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\unknown_field_set_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\wire_format_unittest.cc" + > + </File> + <File + RelativePath="..\src\google\protobuf\io\zero_copy_stream_unittest.cc" + > + </File> + </Filter> + <File + RelativePath="..\src\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating cpp_test_bad_identifiers.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
" + Outputs="google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating cpp_test_bad_identifiers.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
" + Outputs="google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto
" + Outputs="google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto
" + Outputs="google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_custom_options.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_custom_options.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto
" + Outputs="google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_custom_options.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto
" + Outputs="google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_embed_optimize_for.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_embed_optimize_for.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto
" + Outputs="google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_embed_optimize_for.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto
" + Outputs="google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_import.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_import.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto
" + Outputs="google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_import.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto
" + Outputs="google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_lite_imports_nonlite.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_lite_imports_nonlite.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto
" + Outputs="google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_lite_imports_nonlite.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto
" + Outputs="google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_mset.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_mset.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto
" + Outputs="google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_mset.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto
" + Outputs="google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_optimize_for.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_optimize_for.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto
" + Outputs="google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_optimize_for.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto
" + Outputs="google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\src\google\protobuf\unittest_no_generic_services.proto" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_no_generic_services.pb.{h,cc}..." + CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto
" + Outputs="google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Generating unittest_no_generic_services.pb.{h,cc}..." + CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto
" + Outputs="google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc" + /> + </FileConfiguration> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> |