aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWink Saville <wink@google.com>2010-05-29 13:00:38 -0700
committerWink Saville <wink@google.com>2010-05-29 13:00:38 -0700
commitd0332953cda33fb4f8e24ebff9c49159b69c43d6 (patch)
tree81612e8b12f590310aeb0ebf1da37b304eb7baa6 /src
parentede38fe9b9f93888e6e41afc7abb09525f44da95 (diff)
downloadexternal_protobuf-d0332953cda33fb4f8e24ebff9c49159b69c43d6.zip
external_protobuf-d0332953cda33fb4f8e24ebff9c49159b69c43d6.tar.gz
external_protobuf-d0332953cda33fb4f8e24ebff9c49159b69c43d6.tar.bz2
Add protobuf 2.3.0 sources
This is the contents of protobuf-2.3.0.tar.bz2 from http://code.google.com/p/protobuf/downloads/list. Change-Id: Idfde09ce7ef5ac027b07ee83f2674fbbed5c30b2
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am82
-rw-r--r--src/Makefile.in366
-rw-r--r--src/google/protobuf/compiler/code_generator.cc9
-rw-r--r--src/google/protobuf/compiler/code_generator.h13
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc687
-rw-r--r--src/google/protobuf/compiler/command_line_interface.h71
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc654
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc11
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.cc14
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc71
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.h1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_extension.cc21
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.cc29
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.h6
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc59
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc53
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h24
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc108
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.h1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc36
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc121
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.cc78
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.h1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc35
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc73
-rw-r--r--src/google/protobuf/compiler/importer.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc5
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc46
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.h3
-rw-r--r--src/google/protobuf/compiler/java/java_extension.cc65
-rw-r--r--src/google/protobuf/compiler/java/java_field.cc10
-rw-r--r--src/google/protobuf/compiler/java/java_field.h2
-rw-r--r--src/google/protobuf/compiler/java/java_file.cc40
-rw-r--r--src/google/protobuf/compiler/java/java_file.h5
-rw-r--r--src/google/protobuf/compiler/java/java_generator.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.cc43
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h18
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc96
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc18
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.h2
-rw-r--r--src/google/protobuf/compiler/java/java_plugin_unittest.cc121
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc48
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.h3
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_enum.cc96
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_enum.h87
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc333
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_enum_field.h94
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_field.cc102
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_file.cc251
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_file.h94
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_generator.cc209
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_helpers.cc381
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_helpers.h128
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_message.cc474
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_message.h93
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_message_field.cc302
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_message_field.h95
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_params.h143
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc660
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h94
-rw-r--r--src/google/protobuf/compiler/main.cc7
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.cc209
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.h108
-rw-r--r--src/google/protobuf/compiler/parser.cc11
-rw-r--r--src/google/protobuf/compiler/parser_unittest.cc6
-rw-r--r--src/google/protobuf/compiler/plugin.cc152
-rw-r--r--src/google/protobuf/compiler/plugin.h (renamed from src/google/protobuf/compiler/javamicro/javamicro_generator.h)55
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc1084
-rw-r--r--src/google/protobuf/compiler/plugin.pb.h727
-rw-r--r--src/google/protobuf/compiler/plugin.proto145
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc235
-rw-r--r--src/google/protobuf/compiler/python/python_generator.h16
-rw-r--r--src/google/protobuf/compiler/python/python_plugin_unittest.cc116
-rw-r--r--src/google/protobuf/compiler/subprocess.cc458
-rw-r--r--src/google/protobuf/compiler/subprocess.h (renamed from src/google/protobuf/compiler/javamicro/javamicro_field.h)97
-rw-r--r--src/google/protobuf/compiler/test_plugin.cc (renamed from src/google/protobuf/unittest_simple_micro.proto)33
-rwxr-xr-xsrc/google/protobuf/compiler/zip_output_unittest.sh85
-rw-r--r--src/google/protobuf/compiler/zip_writer.cc188
-rw-r--r--src/google/protobuf/compiler/zip_writer.h (renamed from src/google/protobuf/unittest_recursive_micro.proto)42
-rw-r--r--src/google/protobuf/descriptor.cc43
-rw-r--r--src/google/protobuf/descriptor.h23
-rw-r--r--src/google/protobuf/descriptor.pb.cc1363
-rw-r--r--src/google/protobuf/descriptor.pb.h641
-rw-r--r--src/google/protobuf/descriptor.proto22
-rw-r--r--src/google/protobuf/descriptor_database.cc30
-rw-r--r--src/google/protobuf/descriptor_database.h4
-rw-r--r--src/google/protobuf/descriptor_database_unittest.cc34
-rw-r--r--src/google/protobuf/descriptor_unittest.cc3
-rw-r--r--src/google/protobuf/dynamic_message.cc80
-rw-r--r--src/google/protobuf/dynamic_message.h27
-rw-r--r--src/google/protobuf/extension_set.cc314
-rw-r--r--src/google/protobuf/extension_set.h188
-rw-r--r--src/google/protobuf/extension_set_heavy.cc276
-rw-r--r--src/google/protobuf/extension_set_unittest.cc159
-rw-r--r--src/google/protobuf/generated_message_reflection.cc200
-rw-r--r--src/google/protobuf/generated_message_reflection.h17
-rw-r--r--src/google/protobuf/generated_message_util.cc9
-rw-r--r--src/google/protobuf/generated_message_util.h18
-rw-r--r--src/google/protobuf/io/coded_stream.cc379
-rw-r--r--src/google/protobuf/io/coded_stream.h347
-rw-r--r--src/google/protobuf/io/coded_stream_inl.h (renamed from src/google/protobuf/unittest_stringutf8_micro.proto)35
-rw-r--r--src/google/protobuf/io/coded_stream_unittest.cc88
-rw-r--r--src/google/protobuf/io/printer.cc25
-rw-r--r--src/google/protobuf/io/printer.h19
-rw-r--r--src/google/protobuf/io/printer_unittest.cc69
-rw-r--r--src/google/protobuf/io/tokenizer.cc4
-rw-r--r--src/google/protobuf/io/tokenizer.h5
-rw-r--r--src/google/protobuf/io/tokenizer_unittest.cc13
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl.h9
-rw-r--r--src/google/protobuf/io/zero_copy_stream_unittest.cc5
-rw-r--r--src/google/protobuf/message.cc9
-rw-r--r--src/google/protobuf/message.h28
-rw-r--r--src/google/protobuf/message_lite.cc59
-rw-r--r--src/google/protobuf/message_unittest.cc15
-rw-r--r--src/google/protobuf/repeated_field.cc12
-rw-r--r--src/google/protobuf/repeated_field.h275
-rw-r--r--src/google/protobuf/repeated_field_unittest.cc220
-rw-r--r--src/google/protobuf/service.h10
-rw-r--r--src/google/protobuf/stubs/common.h43
-rw-r--r--src/google/protobuf/stubs/hash.h17
-rw-r--r--src/google/protobuf/stubs/once.cc16
-rw-r--r--src/google/protobuf/stubs/once.h26
-rw-r--r--src/google/protobuf/stubs/once_unittest.cc10
-rw-r--r--src/google/protobuf/stubs/structurally_valid.cc81
-rw-r--r--src/google/protobuf/stubs/structurally_valid_unittest.cc14
-rw-r--r--src/google/protobuf/stubs/strutil.cc37
-rw-r--r--src/google/protobuf/stubs/strutil.h9
-rw-r--r--src/google/protobuf/test_util.cc88
-rw-r--r--src/google/protobuf/test_util.h3
-rw-r--r--src/google/protobuf/testing/file.cc13
-rw-r--r--src/google/protobuf/testing/googletest.cc5
-rw-r--r--src/google/protobuf/text_format.cc156
-rw-r--r--src/google/protobuf/text_format.h35
-rw-r--r--src/google/protobuf/text_format_unittest.cc83
-rw-r--r--src/google/protobuf/unittest.proto93
-rw-r--r--src/google/protobuf/unittest_enormous_descriptor.proto1
-rw-r--r--src/google/protobuf/unittest_micro.proto162
-rw-r--r--src/google/protobuf/unittest_no_generic_services.proto (renamed from src/google/protobuf/unittest_import_micro.proto)29
-rw-r--r--src/google/protobuf/unknown_field_set.cc12
-rw-r--r--src/google/protobuf/unknown_field_set.h10
-rw-r--r--src/google/protobuf/wire_format.cc185
-rw-r--r--src/google/protobuf/wire_format_lite.cc175
-rw-r--r--src/google/protobuf/wire_format_lite.h156
-rw-r--r--src/google/protobuf/wire_format_lite_inl.h366
-rw-r--r--src/google/protobuf/wire_format_unittest.cc71
145 files changed, 10825 insertions, 6709 deletions
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 &params)
- : 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 &params) {
- 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 &params);
- ~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 &params);
- ~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 &params);
+ // 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_simple_micro.proto b/src/google/protobuf/compiler/test_plugin.cc
index 057bf3d..5cbbf3d 100644
--- a/src/google/protobuf/unittest_simple_micro.proto
+++ b/src/google/protobuf/compiler/test_plugin.cc
@@ -28,25 +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 SimpleMessageMicro {
- message NestedMessage {
- optional int32 bb = 1;
- }
-
- enum NestedEnum {
- FOO = 1;
- BAR = 2;
- BAZ = 3;
- }
-
- optional int32 d = 1 [default = 123];
- optional NestedMessage nested_msg = 2;
- optional NestedEnum default_nested_enum = 3 [default = BAZ];
+ 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_recursive_micro.proto b/src/google/protobuf/compiler/zip_writer.h
index a256852..4289553 100644
--- a/src/google/protobuf/unittest_recursive_micro.proto
+++ b/src/google/protobuf/compiler/zip_writer.h
@@ -28,20 +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 {
+
+class ZipWriter {
+ public:
+ ZipWriter(io::ZeroCopyOutputStream* raw_output);
+ ~ZipWriter();
-package protobuf_unittest_import;
+ bool Write(const string& filename, const string& contents);
+ bool WriteDirectory();
-option java_package = "com.google.protobuf.micro";
+ private:
+ struct FileInfo {
+ string name;
+ uint32 offset;
+ uint32 size;
+ uint32 crc32;
+ };
-message RecursiveMessageMicro {
- message NestedMessage {
- optional RecursiveMessageMicro a = 1;
- }
+ io::ZeroCopyOutputStream* raw_output_;
+ vector<FileInfo> files_;
+};
- required int32 id = 1;
- optional NestedMessage nested_message = 2;
- optional RecursiveMessageMicro optional_recursive_message_micro = 3;
- repeated RecursiveMessageMicro repeated_recursive_message_micro = 4;
-}
+} // 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/src/google/protobuf/unittest_stringutf8_micro.proto b/src/google/protobuf/io/coded_stream_inl.h
index e4bbe3d..e9799d4 100644
--- a/src/google/protobuf/unittest_stringutf8_micro.proto
+++ b/src/google/protobuf/io/coded_stream_inl.h
@@ -28,14 +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.
-// Author: wink@google.com (Wink Saville)
+// 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.
-package protobuf_unittest_import;
+#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
+#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
-option java_package = "com.google.protobuf.micro";
+#include <google/protobuf/io/coded_stream.h>
+#include <string>
+#include <google/protobuf/stubs/stl_util-inl.h>
-message StringUtf8 {
- optional string id = 1;
- repeated string rs = 2;
+namespace google {
+namespace protobuf {
+namespace io {
+
+inline bool CodedInputStream::InternalReadStringInline(string* buffer,
+ int size) {
+ if (size < 0) return false; // security: size is often user-supplied
+
+ if (BufferSize() >= size) {
+ STLStringResizeUninitialized(buffer, size);
+ memcpy(string_as_array(buffer), buffer_, size);
+ Advance(size);
+ return true;
+ }
+
+ 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/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