1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-20 20:46:03 +08:00

Update protobuf source from v2.4.1 to 2.5.0.

This commit is contained in:
Nicholas Hastings
2014-09-01 11:21:36 -04:00
parent e4ff29c755
commit ec26f9f98e
225 changed files with 16221 additions and 3428 deletions

View File

@ -38,13 +38,26 @@ MAINTAINERCLEANFILES = \
Makefile.in
nobase_include_HEADERS = \
google/protobuf/stubs/atomicops.h \
google/protobuf/stubs/atomicops_internals_arm_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
google/protobuf/stubs/atomicops_internals_macosx.h \
google/protobuf/stubs/atomicops_internals_mips_gcc.h \
google/protobuf/stubs/atomicops_internals_pnacl.h \
google/protobuf/stubs/atomicops_internals_x86_gcc.h \
google/protobuf/stubs/atomicops_internals_x86_msvc.h \
google/protobuf/stubs/common.h \
google/protobuf/stubs/platform_macros.h \
google/protobuf/stubs/once.h \
google/protobuf/stubs/template_util.h \
google/protobuf/stubs/type_traits.h \
google/protobuf/descriptor.h \
google/protobuf/descriptor.pb.h \
google/protobuf/descriptor_database.h \
google/protobuf/dynamic_message.h \
google/protobuf/extension_set.h \
google/protobuf/generated_enum_reflection.h \
google/protobuf/generated_message_util.h \
google/protobuf/generated_message_reflection.h \
google/protobuf/message.h \
@ -77,13 +90,17 @@ nobase_include_HEADERS = \
lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS)
libprotobuf_lite_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
libprotobuf_lite_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined
libprotobuf_lite_la_SOURCES = \
google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
google/protobuf/stubs/atomicops_internals_x86_msvc.cc \
google/protobuf/stubs/common.cc \
google/protobuf/stubs/once.cc \
google/protobuf/stubs/hash.h \
google/protobuf/stubs/map-util.h \
google/protobuf/stubs/stl_util-inl.h \
google/protobuf/stubs/stl_util.h \
google/protobuf/stubs/stringprintf.cc \
google/protobuf/stubs/stringprintf.h \
google/protobuf/extension_set.cc \
google/protobuf/generated_message_util.cc \
google/protobuf/message_lite.cc \
@ -95,7 +112,7 @@ libprotobuf_lite_la_SOURCES = \
google/protobuf/io/zero_copy_stream_impl_lite.cc
libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
libprotobuf_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
libprotobuf_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined
libprotobuf_la_SOURCES = \
$(libprotobuf_lite_la_SOURCES) \
google/protobuf/stubs/strutil.cc \
@ -123,7 +140,7 @@ libprotobuf_la_SOURCES = \
google/protobuf/compiler/parser.cc
libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
libprotoc_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
libprotoc_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined
libprotoc_la_SOURCES = \
google/protobuf/compiler/code_generator.cc \
google/protobuf/compiler/command_line_interface.cc \
@ -150,6 +167,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/cpp/cpp_message.h \
google/protobuf/compiler/cpp/cpp_message_field.cc \
google/protobuf/compiler/cpp/cpp_message_field.h \
google/protobuf/compiler/cpp/cpp_options.h \
google/protobuf/compiler/cpp/cpp_primitive_field.cc \
google/protobuf/compiler/cpp/cpp_primitive_field.h \
google/protobuf/compiler/cpp/cpp_service.cc \
@ -179,6 +197,8 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_service.h \
google/protobuf/compiler/java/java_string_field.cc \
google/protobuf/compiler/java/java_string_field.h \
google/protobuf/compiler/java/java_doc_comment.cc \
google/protobuf/compiler/java/java_doc_comment.h \
google/protobuf/compiler/python/python_generator.cc
bin_PROGRAMS = protoc
@ -191,12 +211,14 @@ protoc_inputs = \
google/protobuf/unittest.proto \
google/protobuf/unittest_empty.proto \
google/protobuf/unittest_import.proto \
google/protobuf/unittest_import_public.proto \
google/protobuf/unittest_mset.proto \
google/protobuf/unittest_optimize_for.proto \
google/protobuf/unittest_embed_optimize_for.proto \
google/protobuf/unittest_custom_options.proto \
google/protobuf/unittest_lite.proto \
google/protobuf/unittest_import_lite.proto \
google/protobuf/unittest_import_public_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
@ -220,7 +242,9 @@ protoc_lite_outputs = \
google/protobuf/unittest_lite.pb.cc \
google/protobuf/unittest_lite.pb.h \
google/protobuf/unittest_import_lite.pb.cc \
google/protobuf/unittest_import_lite.pb.h
google/protobuf/unittest_import_lite.pb.h \
google/protobuf/unittest_import_public_lite.pb.cc \
google/protobuf/unittest_import_public_lite.pb.h
protoc_outputs = \
$(protoc_lite_outputs) \
@ -230,6 +254,8 @@ protoc_outputs = \
google/protobuf/unittest_empty.pb.h \
google/protobuf/unittest_import.pb.cc \
google/protobuf/unittest_import.pb.h \
google/protobuf/unittest_import_public.pb.cc \
google/protobuf/unittest_import_public.pb.h \
google/protobuf/unittest_mset.pb.cc \
google/protobuf/unittest_mset.pb.h \
google/protobuf/unittest_optimize_for.pb.cc \
@ -290,6 +316,9 @@ protobuf_test_SOURCES = \
google/protobuf/stubs/once_unittest.cc \
google/protobuf/stubs/strutil_unittest.cc \
google/protobuf/stubs/structurally_valid_unittest.cc \
google/protobuf/stubs/stringprintf_unittest.cc \
google/protobuf/stubs/template_util_unittest.cc \
google/protobuf/stubs/type_traits_unittest.cc \
google/protobuf/descriptor_database_unittest.cc \
google/protobuf/descriptor_unittest.cc \
google/protobuf/dynamic_message_unittest.cc \
@ -298,6 +327,7 @@ protobuf_test_SOURCES = \
google/protobuf/message_unittest.cc \
google/protobuf/reflection_ops_unittest.cc \
google/protobuf/repeated_field_unittest.cc \
google/protobuf/repeated_field_reflection_unittest.cc \
google/protobuf/text_format_unittest.cc \
google/protobuf/unknown_field_set_unittest.cc \
google/protobuf/wire_format_unittest.cc \
@ -311,9 +341,11 @@ protobuf_test_SOURCES = \
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.h \
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/java/java_doc_comment_unittest.cc \
google/protobuf/compiler/python/python_plugin_unittest.cc \
$(COMMON_TEST_SOURCES)
nodist_protobuf_test_SOURCES = $(protoc_outputs)

View File

@ -1,9 +1,9 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -85,23 +85,33 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(protodir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libprotobuf_lite_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_libprotobuf_lite_la_OBJECTS = common.lo once.lo extension_set.lo \
generated_message_util.lo message_lite.lo repeated_field.lo \
wire_format_lite.lo coded_stream.lo zero_copy_stream.lo \
am_libprotobuf_lite_la_OBJECTS = atomicops_internals_x86_gcc.lo \
atomicops_internals_x86_msvc.lo common.lo once.lo \
stringprintf.lo extension_set.lo generated_message_util.lo \
message_lite.lo repeated_field.lo wire_format_lite.lo \
coded_stream.lo zero_copy_stream.lo \
zero_copy_stream_impl_lite.lo
libprotobuf_lite_la_OBJECTS = $(am_libprotobuf_lite_la_OBJECTS)
libprotobuf_lite_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libprotobuf_lite_la_LDFLAGS) $(LDFLAGS) -o $@
libprotobuf_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__objects_1 = common.lo once.lo extension_set.lo \
generated_message_util.lo message_lite.lo repeated_field.lo \
wire_format_lite.lo coded_stream.lo zero_copy_stream.lo \
am__objects_1 = atomicops_internals_x86_gcc.lo \
atomicops_internals_x86_msvc.lo common.lo once.lo \
stringprintf.lo extension_set.lo generated_message_util.lo \
message_lite.lo repeated_field.lo wire_format_lite.lo \
coded_stream.lo zero_copy_stream.lo \
zero_copy_stream_impl_lite.lo
am_libprotobuf_la_OBJECTS = $(am__objects_1) strutil.lo substitute.lo \
structurally_valid.lo descriptor.lo descriptor.pb.lo \
@ -124,7 +134,7 @@ am_libprotoc_la_OBJECTS = code_generator.lo command_line_interface.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 java_string_field.lo \
python_generator.lo
java_doc_comment.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) \
@ -139,11 +149,13 @@ am_protobuf_lazy_descriptor_test_OBJECTS = \
$(am__objects_2)
am__objects_3 = \
protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT)
protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.$(OBJEXT)
am__objects_4 = $(am__objects_3) \
protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_empty.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_import.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_import_public.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_mset.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_optimize_for.pb.$(OBJEXT) \
protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
@ -166,7 +178,8 @@ am_protobuf_lite_test_OBJECTS = \
protobuf_lite_test-lite_unittest.$(OBJEXT) \
protobuf_lite_test-test_util_lite.$(OBJEXT)
am__objects_5 = protobuf_lite_test-unittest_lite.pb.$(OBJEXT) \
protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT)
protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT) \
protobuf_lite_test-unittest_import_public_lite.pb.$(OBJEXT)
nodist_protobuf_lite_test_OBJECTS = $(am__objects_5)
protobuf_lite_test_OBJECTS = $(am_protobuf_lite_test_OBJECTS) \
$(nodist_protobuf_lite_test_OBJECTS)
@ -183,6 +196,9 @@ am_protobuf_test_OBJECTS = protobuf_test-common_unittest.$(OBJEXT) \
protobuf_test-once_unittest.$(OBJEXT) \
protobuf_test-strutil_unittest.$(OBJEXT) \
protobuf_test-structurally_valid_unittest.$(OBJEXT) \
protobuf_test-stringprintf_unittest.$(OBJEXT) \
protobuf_test-template_util_unittest.$(OBJEXT) \
protobuf_test-type_traits_unittest.$(OBJEXT) \
protobuf_test-descriptor_database_unittest.$(OBJEXT) \
protobuf_test-descriptor_unittest.$(OBJEXT) \
protobuf_test-dynamic_message_unittest.$(OBJEXT) \
@ -191,6 +207,7 @@ am_protobuf_test_OBJECTS = protobuf_test-common_unittest.$(OBJEXT) \
protobuf_test-message_unittest.$(OBJEXT) \
protobuf_test-reflection_ops_unittest.$(OBJEXT) \
protobuf_test-repeated_field_unittest.$(OBJEXT) \
protobuf_test-repeated_field_reflection_unittest.$(OBJEXT) \
protobuf_test-text_format_unittest.$(OBJEXT) \
protobuf_test-unknown_field_set_unittest.$(OBJEXT) \
protobuf_test-wire_format_unittest.$(OBJEXT) \
@ -206,13 +223,16 @@ am_protobuf_test_OBJECTS = protobuf_test-common_unittest.$(OBJEXT) \
protobuf_test-cpp_unittest.$(OBJEXT) \
protobuf_test-cpp_plugin_unittest.$(OBJEXT) \
protobuf_test-java_plugin_unittest.$(OBJEXT) \
protobuf_test-java_doc_comment_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)
protobuf_test-unittest_import_lite.pb.$(OBJEXT) \
protobuf_test-unittest_import_public_lite.pb.$(OBJEXT)
am__objects_8 = $(am__objects_7) protobuf_test-unittest.pb.$(OBJEXT) \
protobuf_test-unittest_empty.pb.$(OBJEXT) \
protobuf_test-unittest_import.pb.$(OBJEXT) \
protobuf_test-unittest_import_public.pb.$(OBJEXT) \
protobuf_test-unittest_mset.pb.$(OBJEXT) \
protobuf_test-unittest_optimize_for.pb.$(OBJEXT) \
protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
@ -285,12 +305,25 @@ DIST_SOURCES = $(libprotobuf_lite_la_SOURCES) \
$(protoc_SOURCES) $(test_plugin_SOURCES) \
$(am__zcgunzip_SOURCES_DIST) $(am__zcgzip_SOURCES_DIST)
DATA = $(nobase_dist_proto_DATA)
am__nobase_include_HEADERS_DIST = google/protobuf/stubs/common.h \
google/protobuf/stubs/once.h google/protobuf/descriptor.h \
google/protobuf/descriptor.pb.h \
am__nobase_include_HEADERS_DIST = google/protobuf/stubs/atomicops.h \
google/protobuf/stubs/atomicops_internals_arm_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
google/protobuf/stubs/atomicops_internals_macosx.h \
google/protobuf/stubs/atomicops_internals_mips_gcc.h \
google/protobuf/stubs/atomicops_internals_pnacl.h \
google/protobuf/stubs/atomicops_internals_x86_gcc.h \
google/protobuf/stubs/atomicops_internals_x86_msvc.h \
google/protobuf/stubs/common.h \
google/protobuf/stubs/platform_macros.h \
google/protobuf/stubs/once.h \
google/protobuf/stubs/template_util.h \
google/protobuf/stubs/type_traits.h \
google/protobuf/descriptor.h google/protobuf/descriptor.pb.h \
google/protobuf/descriptor_database.h \
google/protobuf/dynamic_message.h \
google/protobuf/extension_set.h \
google/protobuf/generated_enum_reflection.h \
google/protobuf/generated_message_util.h \
google/protobuf/generated_message_reflection.h \
google/protobuf/message.h google/protobuf/message_lite.h \
@ -342,6 +375,7 @@ CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@ -365,7 +399,9 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
@ -397,6 +433,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@ -431,7 +468,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@ -478,13 +514,26 @@ MAINTAINERCLEANFILES = \
Makefile.in
nobase_include_HEADERS = \
google/protobuf/stubs/atomicops.h \
google/protobuf/stubs/atomicops_internals_arm_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
google/protobuf/stubs/atomicops_internals_macosx.h \
google/protobuf/stubs/atomicops_internals_mips_gcc.h \
google/protobuf/stubs/atomicops_internals_pnacl.h \
google/protobuf/stubs/atomicops_internals_x86_gcc.h \
google/protobuf/stubs/atomicops_internals_x86_msvc.h \
google/protobuf/stubs/common.h \
google/protobuf/stubs/platform_macros.h \
google/protobuf/stubs/once.h \
google/protobuf/stubs/template_util.h \
google/protobuf/stubs/type_traits.h \
google/protobuf/descriptor.h \
google/protobuf/descriptor.pb.h \
google/protobuf/descriptor_database.h \
google/protobuf/dynamic_message.h \
google/protobuf/extension_set.h \
google/protobuf/generated_enum_reflection.h \
google/protobuf/generated_message_util.h \
google/protobuf/generated_message_reflection.h \
google/protobuf/message.h \
@ -516,13 +565,17 @@ nobase_include_HEADERS = \
lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS)
libprotobuf_lite_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
libprotobuf_lite_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined
libprotobuf_lite_la_SOURCES = \
google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
google/protobuf/stubs/atomicops_internals_x86_msvc.cc \
google/protobuf/stubs/common.cc \
google/protobuf/stubs/once.cc \
google/protobuf/stubs/hash.h \
google/protobuf/stubs/map-util.h \
google/protobuf/stubs/stl_util-inl.h \
google/protobuf/stubs/stl_util.h \
google/protobuf/stubs/stringprintf.cc \
google/protobuf/stubs/stringprintf.h \
google/protobuf/extension_set.cc \
google/protobuf/generated_message_util.cc \
google/protobuf/message_lite.cc \
@ -534,7 +587,7 @@ libprotobuf_lite_la_SOURCES = \
google/protobuf/io/zero_copy_stream_impl_lite.cc
libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
libprotobuf_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
libprotobuf_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined
libprotobuf_la_SOURCES = \
$(libprotobuf_lite_la_SOURCES) \
google/protobuf/stubs/strutil.cc \
@ -562,7 +615,7 @@ libprotobuf_la_SOURCES = \
google/protobuf/compiler/parser.cc
libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
libprotoc_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
libprotoc_la_LDFLAGS = -version-info 8:0:0 -export-dynamic -no-undefined
libprotoc_la_SOURCES = \
google/protobuf/compiler/code_generator.cc \
google/protobuf/compiler/command_line_interface.cc \
@ -589,6 +642,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/cpp/cpp_message.h \
google/protobuf/compiler/cpp/cpp_message_field.cc \
google/protobuf/compiler/cpp/cpp_message_field.h \
google/protobuf/compiler/cpp/cpp_options.h \
google/protobuf/compiler/cpp/cpp_primitive_field.cc \
google/protobuf/compiler/cpp/cpp_primitive_field.h \
google/protobuf/compiler/cpp/cpp_service.cc \
@ -618,6 +672,8 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_service.h \
google/protobuf/compiler/java/java_string_field.cc \
google/protobuf/compiler/java/java_string_field.h \
google/protobuf/compiler/java/java_doc_comment.cc \
google/protobuf/compiler/java/java_doc_comment.h \
google/protobuf/compiler/python/python_generator.cc
protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la
@ -628,12 +684,14 @@ protoc_inputs = \
google/protobuf/unittest.proto \
google/protobuf/unittest_empty.proto \
google/protobuf/unittest_import.proto \
google/protobuf/unittest_import_public.proto \
google/protobuf/unittest_mset.proto \
google/protobuf/unittest_optimize_for.proto \
google/protobuf/unittest_embed_optimize_for.proto \
google/protobuf/unittest_custom_options.proto \
google/protobuf/unittest_lite.proto \
google/protobuf/unittest_import_lite.proto \
google/protobuf/unittest_import_public_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
@ -657,7 +715,9 @@ protoc_lite_outputs = \
google/protobuf/unittest_lite.pb.cc \
google/protobuf/unittest_lite.pb.h \
google/protobuf/unittest_import_lite.pb.cc \
google/protobuf/unittest_import_lite.pb.h
google/protobuf/unittest_import_lite.pb.h \
google/protobuf/unittest_import_public_lite.pb.cc \
google/protobuf/unittest_import_public_lite.pb.h
protoc_outputs = \
$(protoc_lite_outputs) \
@ -667,6 +727,8 @@ protoc_outputs = \
google/protobuf/unittest_empty.pb.h \
google/protobuf/unittest_import.pb.cc \
google/protobuf/unittest_import.pb.h \
google/protobuf/unittest_import_public.pb.cc \
google/protobuf/unittest_import_public.pb.h \
google/protobuf/unittest_mset.pb.cc \
google/protobuf/unittest_mset.pb.h \
google/protobuf/unittest_optimize_for.pb.cc \
@ -707,6 +769,9 @@ protobuf_test_SOURCES = \
google/protobuf/stubs/once_unittest.cc \
google/protobuf/stubs/strutil_unittest.cc \
google/protobuf/stubs/structurally_valid_unittest.cc \
google/protobuf/stubs/stringprintf_unittest.cc \
google/protobuf/stubs/template_util_unittest.cc \
google/protobuf/stubs/type_traits_unittest.cc \
google/protobuf/descriptor_database_unittest.cc \
google/protobuf/descriptor_unittest.cc \
google/protobuf/dynamic_message_unittest.cc \
@ -715,6 +780,7 @@ protobuf_test_SOURCES = \
google/protobuf/message_unittest.cc \
google/protobuf/reflection_ops_unittest.cc \
google/protobuf/repeated_field_unittest.cc \
google/protobuf/repeated_field_reflection_unittest.cc \
google/protobuf/text_format_unittest.cc \
google/protobuf/unknown_field_set_unittest.cc \
google/protobuf/wire_format_unittest.cc \
@ -728,9 +794,11 @@ protobuf_test_SOURCES = \
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.h \
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/java/java_doc_comment_unittest.cc \
google/protobuf/compiler/python/python_plugin_unittest.cc \
$(COMMON_TEST_SOURCES)
@ -784,7 +852,7 @@ all: $(BUILT_SOURCES)
.SUFFIXES:
.SUFFIXES: .cc .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@ -809,9 +877,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@ -845,11 +913,11 @@ clean-libLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libprotobuf-lite.la: $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_DEPENDENCIES)
libprotobuf-lite.la: $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_DEPENDENCIES) $(EXTRA_libprotobuf_lite_la_DEPENDENCIES)
$(libprotobuf_lite_la_LINK) -rpath $(libdir) $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_LIBADD) $(LIBS)
libprotobuf.la: $(libprotobuf_la_OBJECTS) $(libprotobuf_la_DEPENDENCIES)
libprotobuf.la: $(libprotobuf_la_OBJECTS) $(libprotobuf_la_DEPENDENCIES) $(EXTRA_libprotobuf_la_DEPENDENCIES)
$(libprotobuf_la_LINK) -rpath $(libdir) $(libprotobuf_la_OBJECTS) $(libprotobuf_la_LIBADD) $(LIBS)
libprotoc.la: $(libprotoc_la_OBJECTS) $(libprotoc_la_DEPENDENCIES)
libprotoc.la: $(libprotoc_la_OBJECTS) $(libprotoc_la_DEPENDENCIES) $(EXTRA_libprotoc_la_DEPENDENCIES)
$(libprotoc_la_LINK) -rpath $(libdir) $(libprotoc_la_OBJECTS) $(libprotoc_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@ -903,25 +971,25 @@ clean-checkPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
protobuf-lazy-descriptor-test$(EXEEXT): $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_DEPENDENCIES)
protobuf-lazy-descriptor-test$(EXEEXT): $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_DEPENDENCIES) $(EXTRA_protobuf_lazy_descriptor_test_DEPENDENCIES)
@rm -f protobuf-lazy-descriptor-test$(EXEEXT)
$(protobuf_lazy_descriptor_test_LINK) $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_LDADD) $(LIBS)
protobuf-lite-test$(EXEEXT): $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_DEPENDENCIES)
protobuf-lite-test$(EXEEXT): $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_DEPENDENCIES) $(EXTRA_protobuf_lite_test_DEPENDENCIES)
@rm -f protobuf-lite-test$(EXEEXT)
$(protobuf_lite_test_LINK) $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_LDADD) $(LIBS)
protobuf-test$(EXEEXT): $(protobuf_test_OBJECTS) $(protobuf_test_DEPENDENCIES)
protobuf-test$(EXEEXT): $(protobuf_test_OBJECTS) $(protobuf_test_DEPENDENCIES) $(EXTRA_protobuf_test_DEPENDENCIES)
@rm -f protobuf-test$(EXEEXT)
$(protobuf_test_LINK) $(protobuf_test_OBJECTS) $(protobuf_test_LDADD) $(LIBS)
protoc$(EXEEXT): $(protoc_OBJECTS) $(protoc_DEPENDENCIES)
protoc$(EXEEXT): $(protoc_OBJECTS) $(protoc_DEPENDENCIES) $(EXTRA_protoc_DEPENDENCIES)
@rm -f protoc$(EXEEXT)
$(CXXLINK) $(protoc_OBJECTS) $(protoc_LDADD) $(LIBS)
test_plugin$(EXEEXT): $(test_plugin_OBJECTS) $(test_plugin_DEPENDENCIES)
test_plugin$(EXEEXT): $(test_plugin_OBJECTS) $(test_plugin_DEPENDENCIES) $(EXTRA_test_plugin_DEPENDENCIES)
@rm -f test_plugin$(EXEEXT)
$(CXXLINK) $(test_plugin_OBJECTS) $(test_plugin_LDADD) $(LIBS)
zcgunzip$(EXEEXT): $(zcgunzip_OBJECTS) $(zcgunzip_DEPENDENCIES)
zcgunzip$(EXEEXT): $(zcgunzip_OBJECTS) $(zcgunzip_DEPENDENCIES) $(EXTRA_zcgunzip_DEPENDENCIES)
@rm -f zcgunzip$(EXEEXT)
$(CXXLINK) $(zcgunzip_OBJECTS) $(zcgunzip_LDADD) $(LIBS)
zcgzip$(EXEEXT): $(zcgzip_OBJECTS) $(zcgzip_DEPENDENCIES)
zcgzip$(EXEEXT): $(zcgzip_OBJECTS) $(zcgzip_DEPENDENCIES) $(EXTRA_zcgzip_DEPENDENCIES)
@rm -f zcgzip$(EXEEXT)
$(CXXLINK) $(zcgzip_OBJECTS) $(zcgzip_LDADD) $(LIBS)
@ -931,6 +999,8 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops_internals_x86_gcc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops_internals_x86_msvc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/code_generator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coded_stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command_line_interface.Plo@am__quote@
@ -957,6 +1027,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_message_util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzip_stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_doc_comment.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_enum.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_enum_field.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_extension.Plo@am__quote@
@ -988,6 +1059,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po@am__quote@
@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@
@ -996,6 +1069,7 @@ distclean-compile:
@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@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-coded_stream_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po@am__quote@
@ -1012,6 +1086,7 @@ 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_doc_comment_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@
@ -1020,18 +1095,24 @@ distclean-compile:
@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_reflection_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-stringprintf_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-strutil_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-template_util_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-test_util.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-text_format_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-tokenizer_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-type_traits_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_empty.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po@am__quote@
@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@
@ -1044,6 +1125,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reflection_ops.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repeated_field.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringprintf.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@
@ -1084,6 +1166,20 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
atomicops_internals_x86_gcc.lo: google/protobuf/stubs/atomicops_internals_x86_gcc.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_internals_x86_gcc.lo -MD -MP -MF $(DEPDIR)/atomicops_internals_x86_gcc.Tpo -c -o atomicops_internals_x86_gcc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_gcc.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/atomicops_internals_x86_gcc.Tpo $(DEPDIR)/atomicops_internals_x86_gcc.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/atomicops_internals_x86_gcc.cc' object='atomicops_internals_x86_gcc.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 atomicops_internals_x86_gcc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_gcc.cc
atomicops_internals_x86_msvc.lo: google/protobuf/stubs/atomicops_internals_x86_msvc.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_internals_x86_msvc.lo -MD -MP -MF $(DEPDIR)/atomicops_internals_x86_msvc.Tpo -c -o atomicops_internals_x86_msvc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_msvc.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/atomicops_internals_x86_msvc.Tpo $(DEPDIR)/atomicops_internals_x86_msvc.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/atomicops_internals_x86_msvc.cc' object='atomicops_internals_x86_msvc.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 atomicops_internals_x86_msvc.lo `test -f 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc' || echo '$(srcdir)/'`google/protobuf/stubs/atomicops_internals_x86_msvc.cc
common.lo: google/protobuf/stubs/common.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT common.lo -MD -MP -MF $(DEPDIR)/common.Tpo -c -o common.lo `test -f 'google/protobuf/stubs/common.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/common.Tpo $(DEPDIR)/common.Plo
@ -1098,6 +1194,13 @@ once.lo: google/protobuf/stubs/once.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 once.lo `test -f 'google/protobuf/stubs/once.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once.cc
stringprintf.lo: google/protobuf/stubs/stringprintf.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stringprintf.lo -MD -MP -MF $(DEPDIR)/stringprintf.Tpo -c -o stringprintf.lo `test -f 'google/protobuf/stubs/stringprintf.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/stringprintf.Tpo $(DEPDIR)/stringprintf.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/stringprintf.cc' object='stringprintf.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 stringprintf.lo `test -f 'google/protobuf/stubs/stringprintf.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf.cc
extension_set.lo: google/protobuf/extension_set.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extension_set.lo -MD -MP -MF $(DEPDIR)/extension_set.Tpo -c -o extension_set.lo `test -f 'google/protobuf/extension_set.cc' || echo '$(srcdir)/'`google/protobuf/extension_set.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/extension_set.Tpo $(DEPDIR)/extension_set.Plo
@ -1511,6 +1614,13 @@ java_string_field.lo: google/protobuf/compiler/java/java_string_field.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_string_field.lo `test -f 'google/protobuf/compiler/java/java_string_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_string_field.cc
java_doc_comment.lo: google/protobuf/compiler/java/java_doc_comment.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT java_doc_comment.lo -MD -MP -MF $(DEPDIR)/java_doc_comment.Tpo -c -o java_doc_comment.lo `test -f 'google/protobuf/compiler/java/java_doc_comment.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/java_doc_comment.Tpo $(DEPDIR)/java_doc_comment.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_doc_comment.cc' object='java_doc_comment.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 java_doc_comment.lo `test -f 'google/protobuf/compiler/java/java_doc_comment.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment.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@ $(am__mv) $(DEPDIR)/python_generator.Tpo $(DEPDIR)/python_generator.Plo
@ -1602,6 +1712,20 @@ protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj: google/protobuf/unitt
@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_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.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_import_public_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public_lite.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_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.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_import_public_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public_lite.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_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
protobuf_lazy_descriptor_test-unittest.pb.o: google/protobuf/unittest.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.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po
@ -1644,6 +1768,20 @@ protobuf_lazy_descriptor_test-unittest_import.pb.obj: google/protobuf/unittest_i
@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_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
protobuf_lazy_descriptor_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.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_import_public.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public.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_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
protobuf_lazy_descriptor_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.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_import_public.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_lazy_descriptor_test-unittest_import_public.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_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
protobuf_lazy_descriptor_test-unittest_mset.pb.o: google/protobuf/unittest_mset.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_mset.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po
@ -1798,6 +1936,20 @@ protobuf_lite_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
protobuf_lite_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_public_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lite_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
protobuf_lite_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_lite_test-unittest_import_public_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_lite_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
protobuf_test-common_unittest.o: google/protobuf/stubs/common_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-common_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-common_unittest.Tpo $(DEPDIR)/protobuf_test-common_unittest.Po
@ -1854,6 +2006,48 @@ protobuf_test-structurally_valid_unittest.obj: google/protobuf/stubs/structurall
@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-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi`
protobuf_test-stringprintf_unittest.o: google/protobuf/stubs/stringprintf_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-stringprintf_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o protobuf_test-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo $(DEPDIR)/protobuf_test-stringprintf_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/stringprintf_unittest.cc' object='protobuf_test-stringprintf_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-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc
protobuf_test-stringprintf_unittest.obj: google/protobuf/stubs/stringprintf_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-stringprintf_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o protobuf_test-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo $(DEPDIR)/protobuf_test-stringprintf_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/stringprintf_unittest.cc' object='protobuf_test-stringprintf_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-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi`
protobuf_test-template_util_unittest.o: google/protobuf/stubs/template_util_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-template_util_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o protobuf_test-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-template_util_unittest.Tpo $(DEPDIR)/protobuf_test-template_util_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/template_util_unittest.cc' object='protobuf_test-template_util_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-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc
protobuf_test-template_util_unittest.obj: google/protobuf/stubs/template_util_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-template_util_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o protobuf_test-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-template_util_unittest.Tpo $(DEPDIR)/protobuf_test-template_util_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/template_util_unittest.cc' object='protobuf_test-template_util_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-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi`
protobuf_test-type_traits_unittest.o: google/protobuf/stubs/type_traits_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-type_traits_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o protobuf_test-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo $(DEPDIR)/protobuf_test-type_traits_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/type_traits_unittest.cc' object='protobuf_test-type_traits_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-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc
protobuf_test-type_traits_unittest.obj: google/protobuf/stubs/type_traits_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-type_traits_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o protobuf_test-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-type_traits_unittest.Tpo $(DEPDIR)/protobuf_test-type_traits_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/stubs/type_traits_unittest.cc' object='protobuf_test-type_traits_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-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi`
protobuf_test-descriptor_database_unittest.o: google/protobuf/descriptor_database_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-descriptor_database_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo $(DEPDIR)/protobuf_test-descriptor_database_unittest.Po
@ -1966,6 +2160,20 @@ protobuf_test-repeated_field_unittest.obj: google/protobuf/repeated_field_unitte
@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-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi`
protobuf_test-repeated_field_reflection_unittest.o: google/protobuf/repeated_field_reflection_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_reflection_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o protobuf_test-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_reflection_unittest.cc' object='protobuf_test-repeated_field_reflection_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-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc
protobuf_test-repeated_field_reflection_unittest.obj: google/protobuf/repeated_field_reflection_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-repeated_field_reflection_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o protobuf_test-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo $(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/repeated_field_reflection_unittest.cc' object='protobuf_test-repeated_field_reflection_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-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi`
protobuf_test-text_format_unittest.o: google/protobuf/text_format_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-text_format_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-text_format_unittest.Tpo $(DEPDIR)/protobuf_test-text_format_unittest.Po
@ -2176,6 +2384,20 @@ protobuf_test-java_plugin_unittest.obj: google/protobuf/compiler/java/java_plugi
@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-java_doc_comment_unittest.o: google/protobuf/compiler/java/java_doc_comment_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_doc_comment_unittest.o -MD -MP -MF $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='protobuf_test-java_doc_comment_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_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc
protobuf_test-java_doc_comment_unittest.obj: google/protobuf/compiler/java/java_doc_comment_unittest.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-java_doc_comment_unittest.obj -MD -MP -MF $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo $(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='protobuf_test-java_doc_comment_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_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_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@ $(am__mv) $(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo $(DEPDIR)/protobuf_test-python_plugin_unittest.Po
@ -2260,6 +2482,20 @@ protobuf_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.
@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_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
protobuf_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public_lite.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_test-unittest_import_public_lite.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_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
protobuf_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public_lite.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o protobuf_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public_lite.pb.cc' object='protobuf_test-unittest_import_public_lite.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_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
protobuf_test-unittest.pb.o: google/protobuf/unittest.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest.pb.Tpo $(DEPDIR)/protobuf_test-unittest.pb.Po
@ -2302,6 +2538,20 @@ protobuf_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.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-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
protobuf_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o protobuf_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_test-unittest_import_public.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_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
protobuf_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_import_public.pb.obj -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o protobuf_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo $(DEPDIR)/protobuf_test-unittest_import_public.pb.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/unittest_import_public.pb.cc' object='protobuf_test-unittest_import_public.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_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
protobuf_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT protobuf_test-unittest_mset.pb.o -MD -MP -MF $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo $(DEPDIR)/protobuf_test-unittest_mset.pb.Po
@ -2509,9 +2759,7 @@ uninstall-nobase_dist_protoDATA:
@$(NORMAL_UNINSTALL)
@list='$(nobase_dist_proto_DATA)'; test -n "$(protodir)" || list=; \
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(protodir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(protodir)" && rm -f $$files
dir='$(DESTDIR)$(protodir)'; $(am__uninstall_files_from_dir)
install-nobase_includeHEADERS: $(nobase_include_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
@ -2532,9 +2780,7 @@ uninstall-nobase_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(includedir)" && rm -f $$files
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@ -2669,14 +2915,15 @@ check-TESTS: $(TESTS)
fi; \
dashes=`echo "$$dashes" | sed s/./=/g`; \
if test "$$failed" -eq 0; then \
echo "$$grn$$dashes"; \
col="$$grn"; \
else \
echo "$$red$$dashes"; \
col="$$red"; \
fi; \
echo "$$banner"; \
test -z "$$skipped" || echo "$$skipped"; \
test -z "$$report" || echo "$$report"; \
echo "$$dashes$$std"; \
echo "$${col}$$dashes$${std}"; \
echo "$${col}$$banner$${std}"; \
test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
test -z "$$report" || echo "$${col}$$report$${std}"; \
echo "$${col}$$dashes$${std}"; \
test "$$failed" -eq 0; \
else :; fi
@ -2733,10 +2980,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:

View File

@ -59,12 +59,13 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/printer.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/stl_util.h>
namespace google {
@ -145,7 +146,7 @@ void AddTrailingSlash(string* path) {
bool VerifyDirectoryExists(const string& path) {
if (path.empty()) return true;
if (access(path.c_str(), W_OK) == -1) {
if (access(path.c_str(), F_OK) == -1) {
cerr << path << ": " << strerror(errno) << endl;
return false;
} else {
@ -566,6 +567,7 @@ CommandLineInterface::CommandLineInterface()
: mode_(MODE_COMPILE),
error_format_(ERROR_FORMAT_GCC),
imports_in_descriptor_set_(false),
source_info_in_descriptor_set_(false),
disallow_services_(false),
inputs_are_proto_path_relative_(false) {}
CommandLineInterface::~CommandLineInterface() {}
@ -574,9 +576,23 @@ void CommandLineInterface::RegisterGenerator(const string& flag_name,
CodeGenerator* generator,
const string& help_text) {
GeneratorInfo info;
info.flag_name = flag_name;
info.generator = generator;
info.help_text = help_text;
generators_[flag_name] = info;
generators_by_flag_name_[flag_name] = info;
}
void CommandLineInterface::RegisterGenerator(const string& flag_name,
const string& option_flag_name,
CodeGenerator* generator,
const string& help_text) {
GeneratorInfo info;
info.flag_name = flag_name;
info.option_flag_name = option_flag_name;
info.generator = generator;
info.help_text = help_text;
generators_by_flag_name_[flag_name] = info;
generators_by_option_name_[option_flag_name] = info;
}
void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) {
@ -585,7 +601,14 @@ void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) {
int CommandLineInterface::Run(int argc, const char* const argv[]) {
Clear();
if (!ParseArguments(argc, argv)) return 1;
switch (ParseArguments(argc, argv)) {
case PARSE_ARGUMENT_DONE_AND_EXIT:
return 0;
case PARSE_ARGUMENT_FAIL:
return 1;
case PARSE_ARGUMENT_DONE_AND_CONTINUE:
break;
}
// Set up the source tree.
DiskSourceTree source_tree;
@ -713,6 +736,7 @@ void CommandLineInterface::Clear() {
mode_ = MODE_COMPILE;
imports_in_descriptor_set_ = false;
source_info_in_descriptor_set_ = false;
disallow_services_ = false;
}
@ -755,7 +779,8 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative(
return true;
}
bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
CommandLineInterface::ParseArgumentStatus
CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
executable_name_ = argv[0];
// Iterate through all arguments and parse them.
@ -769,41 +794,50 @@ bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
if (name == "--decode") {
cerr << "To decode an unknown message, use --decode_raw." << endl;
}
return false;
return PARSE_ARGUMENT_FAIL;
} else {
++i;
value = argv[i];
}
}
if (!InterpretArgument(name, value)) return false;
ParseArgumentStatus status = InterpretArgument(name, value);
if (status != PARSE_ARGUMENT_DONE_AND_CONTINUE)
return status;
}
// If no --proto_path was given, use the current working directory.
if (proto_path_.empty()) {
proto_path_.push_back(make_pair<string, string>("", "."));
// Don't use make_pair as the old/default standard library on Solaris
// doesn't support it without explicit template parameters, which are
// incompatible with C++0x's make_pair.
proto_path_.push_back(pair<string, string>("", "."));
}
// Check some errror cases.
bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
if (decoding_raw && !input_files_.empty()) {
cerr << "When using --decode_raw, no input files should be given." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
} else if (!decoding_raw && input_files_.empty()) {
cerr << "Missing input file." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
if (mode_ == MODE_COMPILE && output_directives_.empty() &&
descriptor_set_name_.empty()) {
cerr << "Missing output directives." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) {
cerr << "--include_imports only makes sense when combined with "
"--descriptor_set_out." << endl;
}
if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) {
cerr << "--include_source_info only makes sense when combined with "
"--descriptor_set_out." << endl;
}
return true;
return PARSE_ARGUMENT_DONE_AND_CONTINUE;
}
bool CommandLineInterface::ParseArgument(const char* arg,
@ -853,6 +887,7 @@ bool CommandLineInterface::ParseArgument(const char* arg,
if (*name == "-h" || *name == "--help" ||
*name == "--disallow_services" ||
*name == "--include_imports" ||
*name == "--include_source_info" ||
*name == "--version" ||
*name == "--decode_raw") {
// HACK: These are the only flags that don't take a value.
@ -865,7 +900,8 @@ bool CommandLineInterface::ParseArgument(const char* arg,
return true;
}
bool CommandLineInterface::InterpretArgument(const string& name,
CommandLineInterface::ParseArgumentStatus
CommandLineInterface::InterpretArgument(const string& name,
const string& value) {
if (name.empty()) {
// Not a flag. Just a filename.
@ -874,7 +910,7 @@ bool CommandLineInterface::InterpretArgument(const string& name,
"arguments to " << executable_name_ << ". This is actually "
"sort of hard to do. Congrats. Unfortunately it is not valid "
"input so the program is going to die now." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
input_files_.push_back(value);
@ -890,7 +926,7 @@ bool CommandLineInterface::InterpretArgument(const string& name,
string virtual_path;
string disk_path;
int equals_pos = parts[i].find_first_of('=');
string::size_type equals_pos = parts[i].find_first_of('=');
if (equals_pos == string::npos) {
virtual_path = "";
disk_path = parts[i];
@ -902,7 +938,7 @@ bool CommandLineInterface::InterpretArgument(const string& name,
if (disk_path.empty()) {
cerr << "--proto_path passed empty directory name. (Use \".\" for "
"current directory.)" << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
// Make sure disk path exists, warn otherwise.
@ -910,35 +946,45 @@ bool CommandLineInterface::InterpretArgument(const string& name,
cerr << disk_path << ": warning: directory does not exist." << endl;
}
proto_path_.push_back(make_pair<string, string>(virtual_path, disk_path));
// Don't use make_pair as the old/default standard library on Solaris
// doesn't support it without explicit template parameters, which are
// incompatible with C++0x's make_pair.
proto_path_.push_back(pair<string, string>(virtual_path, disk_path));
}
} else if (name == "-o" || name == "--descriptor_set_out") {
if (!descriptor_set_name_.empty()) {
cerr << name << " may only be passed once." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
if (value.empty()) {
cerr << name << " requires a non-empty value." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
if (mode_ != MODE_COMPILE) {
cerr << "Cannot use --encode or --decode and generate descriptors at the "
"same time." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
descriptor_set_name_ = value;
} else if (name == "--include_imports") {
if (imports_in_descriptor_set_) {
cerr << name << " may only be passed once." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
imports_in_descriptor_set_ = true;
} else if (name == "--include_source_info") {
if (source_info_in_descriptor_set_) {
cerr << name << " may only be passed once." << endl;
return PARSE_ARGUMENT_FAIL;
}
source_info_in_descriptor_set_ = true;
} else if (name == "-h" || name == "--help") {
PrintHelpText();
return false; // Exit without running compiler.
return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
} else if (name == "--version") {
if (!version_info_.empty()) {
@ -947,7 +993,7 @@ bool CommandLineInterface::InterpretArgument(const string& name,
cout << "libprotoc "
<< protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION)
<< endl;
return false; // Exit without running compiler.
return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler.
} else if (name == "--disallow_services") {
disallow_services_ = true;
@ -956,12 +1002,12 @@ bool CommandLineInterface::InterpretArgument(const string& name,
name == "--decode_raw") {
if (mode_ != MODE_COMPILE) {
cerr << "Only one of --encode and --decode can be specified." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
cerr << "Cannot use " << name
<< " and generate code or descriptors at the same time." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
@ -971,10 +1017,10 @@ bool CommandLineInterface::InterpretArgument(const string& name,
if (name == "--decode") {
cerr << "To decode an unknown message, use --decode_raw." << endl;
}
return false;
return PARSE_ARGUMENT_FAIL;
} else if (!value.empty() && name == "--decode_raw") {
cerr << "--decode_raw does not take a parameter." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
codec_type_ = value;
@ -986,16 +1032,16 @@ bool CommandLineInterface::InterpretArgument(const string& name,
error_format_ = ERROR_FORMAT_MSVS;
} else {
cerr << "Unknown error format: " << value << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
} else if (name == "--plugin") {
if (plugin_prefix_.empty()) {
cerr << "This compiler does not support plugins." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
string name;
string plugin_name;
string path;
string::size_type equals_pos = value.find_first_of('=');
@ -1003,32 +1049,42 @@ bool CommandLineInterface::InterpretArgument(const string& name,
// Use the basename of the file.
string::size_type slash_pos = value.find_last_of('/');
if (slash_pos == string::npos) {
name = value;
plugin_name = value;
} else {
name = value.substr(slash_pos + 1);
plugin_name = value.substr(slash_pos + 1);
}
path = value;
} else {
name = value.substr(0, equals_pos);
plugin_name = value.substr(0, equals_pos);
path = value.substr(equals_pos + 1);
}
plugins_[name] = path;
plugins_[plugin_name] = path;
} else {
// Some other flag. Look it up in the generators list.
const GeneratorInfo* generator_info = FindOrNull(generators_, name);
const GeneratorInfo* generator_info =
FindOrNull(generators_by_flag_name_, name);
if (generator_info == NULL &&
(plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) {
// Check if it's a generator option flag.
generator_info = FindOrNull(generators_by_option_name_, name);
if (generator_info == NULL) {
cerr << "Unknown flag: " << name << endl;
return false;
return PARSE_ARGUMENT_FAIL;
} else {
string* parameters = &generator_parameters_[generator_info->flag_name];
if (!parameters->empty()) {
parameters->append(",");
}
parameters->append(value);
}
} else {
// It's an output flag. Add it to the output directives.
if (mode_ != MODE_COMPILE) {
cerr << "Cannot use --encode or --decode and generate code at the "
"same time." << endl;
return false;
return PARSE_ARGUMENT_FAIL;
}
OutputDirective directive;
@ -1052,8 +1108,9 @@ bool CommandLineInterface::InterpretArgument(const string& name,
output_directives_.push_back(directive);
}
}
return true;
return PARSE_ARGUMENT_DONE_AND_CONTINUE;
}
void CommandLineInterface::PrintHelpText() {
@ -1086,6 +1143,12 @@ void CommandLineInterface::PrintHelpText() {
" --include_imports When using --descriptor_set_out, also include\n"
" all dependencies of the input files in the\n"
" set, so that the set is self-contained.\n"
" --include_source_info When using --descriptor_set_out, do not strip\n"
" SourceCodeInfo from the FileDescriptorProto.\n"
" This results in vastly larger descriptors that\n"
" include information about the original\n"
" location of each decl in the source file as\n"
" well as surrounding comments.\n"
" --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;
@ -1101,8 +1164,8 @@ void CommandLineInterface::PrintHelpText() {
" the executable's own name differs." << endl;
}
for (GeneratorMap::iterator iter = generators_.begin();
iter != generators_.end(); ++iter) {
for (GeneratorMap::iterator iter = generators_by_flag_name_.begin();
iter != generators_by_flag_name_.end(); ++iter) {
// FIXME(kenton): If the text is long enough it will wrap, which is ugly,
// but fixing this nicely (e.g. splitting on spaces) is probably more
// trouble than it's worth.
@ -1136,9 +1199,15 @@ bool CommandLineInterface::GenerateOutput(
}
} else {
// Regular generator.
string parameters = output_directive.parameter;
if (!generator_parameters_[output_directive.name].empty()) {
if (!parameters.empty()) {
parameters.append(",");
}
parameters.append(generator_parameters_[output_directive.name]);
}
for (int i = 0; i < parsed_files.size(); i++) {
if (!output_directive.generator->Generate(
parsed_files[i], output_directive.parameter,
if (!output_directive.generator->Generate(parsed_files[i], parameters,
generator_context, &error)) {
// Generator returned an error.
cerr << output_directive.name << ": " << parsed_files[i]->name() << ": "
@ -1168,8 +1237,9 @@ bool CommandLineInterface::GeneratePluginOutput(
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());
GetTransitiveDependencies(parsed_files[i],
true, // Include source code info.
&already_seen, request.mutable_proto_file());
}
// Invoke the plugin.
@ -1299,12 +1369,17 @@ bool CommandLineInterface::WriteDescriptorSet(
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());
GetTransitiveDependencies(parsed_files[i],
source_info_in_descriptor_set_,
&already_seen, file_set.mutable_file());
}
} else {
for (int i = 0; i < parsed_files.size(); i++) {
parsed_files[i]->CopyTo(file_set.add_file());
FileDescriptorProto* file_proto = file_set.add_file();
parsed_files[i]->CopyTo(file_proto);
if (source_info_in_descriptor_set_) {
parsed_files[i]->CopySourceCodeInfoTo(file_proto);
}
}
}
@ -1334,7 +1409,7 @@ bool CommandLineInterface::WriteDescriptorSet(
}
void CommandLineInterface::GetTransitiveDependencies(
const FileDescriptor* file,
const FileDescriptor* file, bool include_source_code_info,
set<const FileDescriptor*>* already_seen,
RepeatedPtrField<FileDescriptorProto>* output) {
if (!already_seen->insert(file).second) {
@ -1344,11 +1419,16 @@ void CommandLineInterface::GetTransitiveDependencies(
// Add all dependencies.
for (int i = 0; i < file->dependency_count(); i++) {
GetTransitiveDependencies(file->dependency(i), already_seen, output);
GetTransitiveDependencies(file->dependency(i), include_source_code_info,
already_seen, output);
}
// Add this file.
file->CopyTo(output->Add());
FileDescriptorProto* new_descriptor = output->Add();
file->CopyTo(new_descriptor);
if (include_source_code_info) {
file->CopySourceCodeInfoTo(new_descriptor);
}
}

View File

@ -112,6 +112,19 @@ class LIBPROTOC_EXPORT CommandLineInterface {
CodeGenerator* generator,
const string& help_text);
// Register a code generator for a language.
// Besides flag_name you can specify another option_flag_name that could be
// used to pass extra parameters to the registered code generator.
// Suppose you have registered a generator by calling:
// command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
// Then you could invoke the compiler with a command like:
// protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
// This will pass "enable_bar,enable_baz" as the parameter to the generator.
void RegisterGenerator(const string& flag_name,
const string& option_flag_name,
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.
@ -186,8 +199,15 @@ class LIBPROTOC_EXPORT CommandLineInterface {
bool MakeInputsBeProtoPathRelative(
DiskSourceTree* source_tree);
// Return status for ParseArguments() and InterpretArgument().
enum ParseArgumentStatus {
PARSE_ARGUMENT_DONE_AND_CONTINUE,
PARSE_ARGUMENT_DONE_AND_EXIT,
PARSE_ARGUMENT_FAIL
};
// Parse all command-line arguments.
bool ParseArguments(int argc, const char* const argv[]);
ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);
// Parses a command-line argument into a name/value pair. Returns
// true if the next argument in the argv should be used as the value,
@ -203,7 +223,8 @@ class LIBPROTOC_EXPORT CommandLineInterface {
bool ParseArgument(const char* arg, string* name, string* value);
// Interprets arguments parsed with ParseArgument.
bool InterpretArgument(const string& name, const string& value);
ParseArgumentStatus InterpretArgument(const string& name,
const string& value);
// Print the --help text to stderr.
void PrintHelpText();
@ -230,9 +251,11 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// 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.
// added will be inserted into *already_seen. If include_source_code_info is
// true then include the source code information in the FileDescriptorProtos.
static void GetTransitiveDependencies(
const FileDescriptor* file,
bool include_source_code_info,
set<const FileDescriptor*>* already_seen,
RepeatedPtrField<FileDescriptorProto>* output);
@ -244,13 +267,21 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// Version info set with SetVersionInfo().
string version_info_;
// Map from flag names to registered generators.
// Registered generators.
struct GeneratorInfo {
string flag_name;
string option_flag_name;
CodeGenerator* generator;
string help_text;
};
typedef map<string, GeneratorInfo> GeneratorMap;
GeneratorMap generators_;
GeneratorMap generators_by_flag_name_;
GeneratorMap generators_by_option_name_;
// A map from generator names to the parameters specified using the option
// flag. For example, if the user invokes the compiler with:
// protoc --foo_out=outputdir --foo_opt=enable_bar ...
// Then there will be an entry ("--foo_out", "enable_bar") in this map.
map<string, string> generator_parameters_;
// See AllowPlugins(). If this is empty, plugins aren't allowed.
string plugin_prefix_;
@ -302,6 +333,10 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// the .proto files listed on the command-line are added.
bool imports_in_descriptor_set_;
// True if --include_source_info was given, meaning that we should not strip
// SourceCodeInfo from the DescriptorSet.
bool source_info_in_descriptor_set_;
// Was the --disallow_services flag used?
bool disallow_services_;

View File

@ -122,6 +122,10 @@ class CommandLineInterfaceTest : public testing::Test {
// substring.
void ExpectErrorSubstring(const string& expected_substring);
// Like ExpectErrorSubstring, but checks that Run() returned zero.
void ExpectErrorSubstringWithZeroReturnCode(
const string& expected_substring);
// Returns true if ExpectErrorSubstring(expected_substring) would pass, but
// does not fail otherwise.
bool HasAlternateErrorSubstring(const string& expected_substring);
@ -225,7 +229,7 @@ void CommandLineInterfaceTest::SetUp() {
// Register generators.
CodeGenerator* generator = new MockCodeGenerator("test_generator");
mock_generators_to_delete_.push_back(generator);
cli_.RegisterGenerator("--test_out", generator, "Test output.");
cli_.RegisterGenerator("--test_out", "--test_opt", generator, "Test output.");
cli_.RegisterGenerator("-t", generator, "Test output.");
generator = new MockCodeGenerator("alt_generator");
@ -345,6 +349,12 @@ void CommandLineInterfaceTest::ExpectErrorSubstring(
EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
}
void CommandLineInterfaceTest::ExpectErrorSubstringWithZeroReturnCode(
const string& expected_substring) {
EXPECT_EQ(0, return_code_);
EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
}
bool CommandLineInterfaceTest::HasAlternateErrorSubstring(
const string& expected_substring) {
EXPECT_NE(0, return_code_);
@ -544,6 +554,32 @@ TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) {
// Test that generator parameters specified with the option flag are
// correctly passed to the code generator.
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
// Create the "a" and "b" sub-directories.
CreateTempDir("a");
CreateTempDir("b");
Run("protocol_compiler "
"--test_opt=foo1 "
"--test_out=bar:$tmpdir/a "
"--test_opt=foo2 "
"--test_out=baz:$tmpdir/b "
"--test_opt=foo3 "
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
ExpectGenerated(
"test_generator", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a");
ExpectGenerated(
"test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
}
TEST_F(CommandLineInterfaceTest, Insert) {
// Test running a generator that inserts code into another's output.
@ -779,6 +815,33 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
if (HasFatalFailure()) return;
ASSERT_EQ(1, descriptor_set.file_size());
EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
// Descriptor set should not have source code info.
EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
}
TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
CreateTempFile("bar.proto",
"syntax = \"proto2\";\n"
"import \"foo.proto\";\n"
"message Bar {\n"
" optional Foo foo = 1;\n"
"}\n");
Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
"--include_source_info --proto_path=$tmpdir bar.proto");
ExpectNoErrors();
FileDescriptorSet descriptor_set;
ReadDescriptorSet("descriptor_set", &descriptor_set);
if (HasFatalFailure()) return;
ASSERT_EQ(1, descriptor_set.file_size());
EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
// Source code info included.
EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
}
TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
@ -807,6 +870,40 @@ TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
}
EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
// Descriptor set should not have source code info.
EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
EXPECT_FALSE(descriptor_set.file(1).has_source_code_info());
}
TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSetWithSourceInfo) {
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
CreateTempFile("bar.proto",
"syntax = \"proto2\";\n"
"import \"foo.proto\";\n"
"message Bar {\n"
" optional Foo foo = 1;\n"
"}\n");
Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
"--include_imports --include_source_info --proto_path=$tmpdir bar.proto");
ExpectNoErrors();
FileDescriptorSet descriptor_set;
ReadDescriptorSet("descriptor_set", &descriptor_set);
if (HasFatalFailure()) return;
ASSERT_EQ(2, descriptor_set.file_size());
if (descriptor_set.file(0).name() == "bar.proto") {
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());
// Source code info included.
EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
EXPECT_TRUE(descriptor_set.file(1).has_source_code_info());
}
// -------------------------------------------------------------------
@ -1129,6 +1226,17 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) {
#endif
}
TEST_F(CommandLineInterfaceTest, PluginReceivesSourceCodeInfo) {
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message MockCodeGenerator_HasSourceCodeInfo {}\n");
Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
ExpectErrorSubstring(
"Saw message type MockCodeGenerator_HasSourceCodeInfo: 1.");
}
TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
// Test what happens if the plugin isn't found.
@ -1171,11 +1279,11 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) {
TEST_F(CommandLineInterfaceTest, HelpText) {
Run("test_exec_name --help");
ExpectErrorSubstring("Usage: test_exec_name ");
ExpectErrorSubstring("--test_out=OUT_DIR");
ExpectErrorSubstring("Test output.");
ExpectErrorSubstring("--alt_out=OUT_DIR");
ExpectErrorSubstring("Alt output.");
ExpectErrorSubstringWithZeroReturnCode("Usage: test_exec_name ");
ExpectErrorSubstringWithZeroReturnCode("--test_out=OUT_DIR");
ExpectErrorSubstringWithZeroReturnCode("Test output.");
ExpectErrorSubstringWithZeroReturnCode("--alt_out=OUT_DIR");
ExpectErrorSubstringWithZeroReturnCode("Alt output.");
}
TEST_F(CommandLineInterfaceTest, GccFormatErrors) {

View File

@ -48,8 +48,8 @@
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/stl_util-inl.h>
#include <google/protobuf/stubs/map-util.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>

View File

@ -46,10 +46,10 @@ namespace compiler {
namespace cpp {
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
const string& dllexport_decl)
const Options& options)
: descriptor_(descriptor),
classname_(ClassName(descriptor, false)),
dllexport_decl_(dllexport_decl) {
options_(options) {
}
EnumGenerator::~EnumGenerator() {}
@ -88,10 +88,10 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
vars["min_name"] = min_value->name();
vars["max_name"] = max_value->name();
if (dllexport_decl_.empty()) {
if (options_.dllexport_decl.empty()) {
vars["dllexport"] = "";
} else {
vars["dllexport"] = dllexport_decl_ + " ";
vars["dllexport"] = options_.dllexport_decl + " ";
}
printer->Print(vars,

View File

@ -36,8 +36,10 @@
#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
#include <string>
#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
namespace io {
@ -53,7 +55,7 @@ class EnumGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit EnumGenerator(const EnumDescriptor* descriptor,
const string& dllexport_decl);
const Options& options);
~EnumGenerator();
// Header stuff.
@ -86,7 +88,7 @@ class EnumGenerator {
private:
const EnumDescriptor* descriptor_;
string classname_;
string dllexport_decl_;
Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
};

View File

@ -46,8 +46,9 @@ namespace cpp {
namespace {
void SetEnumVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, variables);
map<string, string>* variables,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
(*variables)["type"] = ClassName(descriptor->enum_type(), true);
(*variables)["default"] = SimpleItoa(default_value->number());
@ -58,9 +59,10 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
// ===================================================================
EnumFieldGenerator::
EnumFieldGenerator(const FieldDescriptor* descriptor)
EnumFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetEnumVariables(descriptor, &variables_);
SetEnumVariables(descriptor, &variables_, options);
}
EnumFieldGenerator::~EnumFieldGenerator() {}
@ -84,7 +86,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" return static_cast< $type$ >($name$_);\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
" GOOGLE_DCHECK($type$_IsValid(value));\n"
" assert($type$_IsValid(value));\n"
" set_has_$name$();\n"
" $name$_ = value;\n"
"}\n");
@ -152,9 +154,10 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
RepeatedEnumFieldGenerator::
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetEnumVariables(descriptor, &variables_);
SetEnumVariables(descriptor, &variables_, options);
}
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
@ -187,11 +190,11 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" return static_cast< $type$ >($name$_.Get(index));\n"
"}\n"
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
" GOOGLE_DCHECK($type$_IsValid(value));\n"
" assert($type$_IsValid(value));\n"
" $name$_.Set(index, value);\n"
"}\n"
"inline void $classname$::add_$name$($type$ value) {\n"
" GOOGLE_DCHECK($type$_IsValid(value));\n"
" assert($type$_IsValid(value));\n"
" $name$_.Add(value);\n"
"}\n");
printer->Print(variables_,
@ -345,7 +348,9 @@ GenerateByteSize(io::Printer* printer) const {
" total_size += $tag_size$ +\n"
" ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
"}\n"
"GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
"_$name$_cached_byte_size_ = data_size;\n"
"GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
"total_size += data_size;\n");
} else {
printer->Print(variables_,

View File

@ -46,7 +46,8 @@ namespace cpp {
class EnumFieldGenerator : public FieldGenerator {
public:
explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
explicit EnumFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~EnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
@ -71,7 +72,8 @@ class EnumFieldGenerator : public FieldGenerator {
class RepeatedEnumFieldGenerator : public FieldGenerator {
public:
explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~RepeatedEnumFieldGenerator();
// implements FieldGenerator ---------------------------------------

View File

@ -57,9 +57,9 @@ string ExtendeeClassName(const FieldDescriptor* descriptor) {
} // anonymous namespace
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
const string& dllexport_decl)
const Options& options)
: descriptor_(descriptor),
dllexport_decl_(dllexport_decl) {
options_(options) {
// Construct type_traits_.
if (descriptor_->is_repeated()) {
type_traits_ = "Repeated";
@ -106,8 +106,8 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
// export/import specifier.
if (descriptor_->extension_scope() == NULL) {
vars["qualifier"] = "extern";
if (!dllexport_decl_.empty()) {
vars["qualifier"] = dllexport_decl_ + " " + vars["qualifier"];
if (!options_.dllexport_decl.empty()) {
vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"];
}
} else {
vars["qualifier"] = "static";

View File

@ -37,6 +37,7 @@
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@ -56,8 +57,8 @@ namespace cpp {
class ExtensionGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit ExtensionGenerator(const FieldDescriptor* descriptor,
const string& dllexport_decl);
explicit ExtensionGenerator(const FieldDescriptor* desycriptor,
const Options& options);
~ExtensionGenerator();
// Header stuff.
@ -72,7 +73,7 @@ class ExtensionGenerator {
private:
const FieldDescriptor* descriptor_;
string type_traits_;
string dllexport_decl_;
Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
};

View File

@ -52,7 +52,8 @@ namespace cpp {
using internal::WireFormat;
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
map<string, string>* variables,
const Options& options) {
(*variables)["name"] = FieldName(descriptor);
(*variables)["index"] = SimpleItoa(descriptor->index());
(*variables)["number"] = SimpleItoa(descriptor->number());
@ -64,6 +65,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["deprecation"] = descriptor->options().deprecated()
? " PROTOBUF_DEPRECATED" : "";
(*variables)["cppget"] = "Get";
}
FieldGenerator::~FieldGenerator() {}
@ -80,46 +82,47 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
}
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
const Options& options)
: descriptor_(descriptor),
field_generators_(
new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
field_generators_(new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
// Construct all the FieldGenerators.
for (int i = 0; i < descriptor->field_count(); i++) {
field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
field_generators_[i].reset(MakeGenerator(descriptor->field(i), options));
}
}
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
const Options& options) {
if (field->is_repeated()) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
return new RepeatedMessageFieldGenerator(field);
return new RepeatedMessageFieldGenerator(field, options);
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // RepeatedStringFieldGenerator handles unknown ctypes.
case FieldOptions::STRING:
return new RepeatedStringFieldGenerator(field);
return new RepeatedStringFieldGenerator(field, options);
}
case FieldDescriptor::CPPTYPE_ENUM:
return new RepeatedEnumFieldGenerator(field);
return new RepeatedEnumFieldGenerator(field, options);
default:
return new RepeatedPrimitiveFieldGenerator(field);
return new RepeatedPrimitiveFieldGenerator(field, options);
}
} else {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
return new MessageFieldGenerator(field);
return new MessageFieldGenerator(field, options);
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // StringFieldGenerator handles unknown ctypes.
case FieldOptions::STRING:
return new StringFieldGenerator(field);
return new StringFieldGenerator(field, options);
}
case FieldDescriptor::CPPTYPE_ENUM:
return new EnumFieldGenerator(field);
return new EnumFieldGenerator(field, options);
default:
return new PrimitiveFieldGenerator(field);
return new PrimitiveFieldGenerator(field, options);
}
}
}

View File

@ -40,6 +40,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@ -57,7 +58,8 @@ namespace cpp {
// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
// 'deprecation'].
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
map<string, string>* variables);
map<string, string>* variables,
const Options& options);
class FieldGenerator {
public:
@ -114,6 +116,13 @@ class FieldGenerator {
// Most field types don't need this, so the default implementation is empty.
virtual void GenerateDestructorCode(io::Printer* printer) const {}
// Generate code that allocates the fields's default instance.
virtual void GenerateDefaultInstanceAllocator(io::Printer* printer) const {}
// Generate code that should be run when ShutdownProtobufLibrary() is called,
// to delete all dynamically-allocated objects.
virtual void GenerateShutdownCode(io::Printer* printer) const {}
// Generate lines to decode this field, which will be placed inside the
// message's MergeFromCodedStream() method.
virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0;
@ -144,7 +153,7 @@ class FieldGenerator {
// Convenience class which constructs FieldGenerators for a Descriptor.
class FieldGeneratorMap {
public:
explicit FieldGeneratorMap(const Descriptor* descriptor);
explicit FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
~FieldGeneratorMap();
const FieldGenerator& get(const FieldDescriptor* field) const;
@ -153,7 +162,8 @@ class FieldGeneratorMap {
const Descriptor* descriptor_;
scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
const Options& options);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
};

View File

@ -51,7 +51,7 @@ namespace cpp {
// ===================================================================
FileGenerator::FileGenerator(const FileDescriptor* file,
const string& dllexport_decl)
const Options& options)
: file_(file),
message_generators_(
new scoped_ptr<MessageGenerator>[file->message_type_count()]),
@ -61,26 +61,26 @@ FileGenerator::FileGenerator(const FileDescriptor* file,
new scoped_ptr<ServiceGenerator>[file->service_count()]),
extension_generators_(
new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
dllexport_decl_(dllexport_decl) {
options_(options) {
for (int i = 0; i < file->message_type_count(); i++) {
message_generators_[i].reset(
new MessageGenerator(file->message_type(i), dllexport_decl));
new MessageGenerator(file->message_type(i), options));
}
for (int i = 0; i < file->enum_type_count(); i++) {
enum_generators_[i].reset(
new EnumGenerator(file->enum_type(i), dllexport_decl));
new EnumGenerator(file->enum_type(i), options));
}
for (int i = 0; i < file->service_count(); i++) {
service_generators_[i].reset(
new ServiceGenerator(file->service(i), dllexport_decl));
new ServiceGenerator(file->service(i), options));
}
for (int i = 0; i < file->extension_count(); i++) {
extension_generators_[i].reset(
new ExtensionGenerator(file->extension(i), dllexport_decl));
new ExtensionGenerator(file->extension(i), options));
}
SplitStringUsing(file_->package(), ".", &package_parts_);
@ -104,6 +104,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"filename", file_->name(),
"filename_identifier", filename_identifier);
printer->Print(
"#include <google/protobuf/stubs/common.h>\n"
"\n");
@ -128,13 +129,23 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
// OK, it's now safe to #include other files.
printer->Print(
"#include <google/protobuf/generated_message_util.h>\n"
"#include <google/protobuf/generated_message_util.h>\n");
if (file_->message_type_count() > 0) {
if (HasDescriptorMethods(file_)) {
printer->Print(
"#include <google/protobuf/message.h>\n");
} else {
printer->Print(
"#include <google/protobuf/message_lite.h>\n");
}
}
printer->Print(
"#include <google/protobuf/repeated_field.h>\n"
"#include <google/protobuf/extension_set.h>\n");
if (HasDescriptorMethods(file_)) {
if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) {
printer->Print(
"#include <google/protobuf/generated_message_reflection.h>\n");
"#include <google/protobuf/generated_enum_reflection.h>\n");
}
if (HasGenericServices(file_)) {
@ -142,6 +153,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"#include <google/protobuf/service.h>\n");
}
if (HasUnknownFields(file_) && file_->message_type_count() > 0) {
printer->Print(
"#include <google/protobuf/unknown_field_set.h>\n");
}
for (int i = 0; i < file_->dependency_count(); i++) {
printer->Print(
@ -149,9 +165,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"dependency", StripProto(file_->dependency(i)->name()));
}
printer->Print(
"// @@protoc_insertion_point(includes)\n");
// Open namespace.
GenerateNamespaceOpeners(printer);
@ -162,7 +180,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"// Internal implementation detail -- do not call these.\n"
"void $dllexport_decl$ $adddescriptorsname$();\n",
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
"dllexport_decl", dllexport_decl_);
"dllexport_decl", options_.dllexport_decl);
printer->Print(
// Note that we don't put dllexport_decl on these because they are only
@ -282,6 +300,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
void FileGenerator::GenerateSource(io::Printer* printer) {
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"// source: $filename$\n"
"\n"
// The generated code calls accessors that might be deprecated. We don't
@ -291,14 +310,17 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"\n"
"#include <algorithm>\n" // for swap()
"\n"
"#include <google/protobuf/stubs/common.h>\n"
"#include <google/protobuf/stubs/once.h>\n"
"#include <google/protobuf/io/coded_stream.h>\n"
"#include <google/protobuf/wire_format_lite_inl.h>\n",
"filename", file_->name(),
"basename", StripProto(file_->name()));
if (HasDescriptorMethods(file_)) {
printer->Print(
"#include <google/protobuf/descriptor.h>\n"
"#include <google/protobuf/generated_message_reflection.h>\n"
"#include <google/protobuf/reflection_ops.h>\n"
"#include <google/protobuf/wire_format.h>\n");
}
@ -381,11 +403,12 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// AddDescriptors() is a file-level procedure which adds the encoded
// FileDescriptorProto for this .proto file to the global DescriptorPool
// for generated files (DescriptorPool::generated_pool()). It always runs
// at static initialization time, so all files will be registered before
// main() starts. This procedure also constructs default instances and
// registers extensions.
// FileDescriptorProto for this .proto file to the global DescriptorPool for
// generated files (DescriptorPool::generated_pool()). It either runs at
// static initialization time (by default) or when default_instance() is
// called for the first time (in LITE_RUNTIME mode with
// GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
// constructs default instances and registers extensions.
//
// Its sibling, AssignDescriptors(), actually pulls the compiled
// FileDescriptor from the DescriptorPool and uses it to populate all of
@ -489,22 +512,29 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
printer->Outdent();
printer->Print(
"}\n");
"}\n\n");
// -----------------------------------------------------------------
// Now generate the AddDescriptors() function.
printer->Print(
"\n"
PrintHandlingOptionalStaticInitializers(
file_, printer,
// With static initializers.
// Note that we don't need any special synchronization in the following code
// because it is called at static init time before any threads exist.
"void $adddescriptorsname$() {\n"
// We don't need any special synchronization here because this code is
// called at static init time before any threads exist.
" static bool already_here = false;\n"
" if (already_here) return;\n"
" already_here = true;\n"
" GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
"\n",
// Without.
"void $adddescriptorsname$_impl() {\n"
" GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
"\n",
// Vars.
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
printer->Indent();
// Call the AddDescriptors() methods for all of our dependencies, to make
@ -515,9 +545,9 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
vector<string> dependency_package_parts;
SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
printer->Print("::");
for (int i = 0; i < dependency_package_parts.size(); i++) {
for (int j = 0; j < dependency_package_parts.size(); j++) {
printer->Print("$name$::",
"name", dependency_package_parts[i]);
"name", dependency_package_parts[j]);
}
// Call its AddDescriptors function.
printer->Print(
@ -541,7 +571,9 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
static const int kBytesPerLine = 40;
for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
printer->Print("\n \"$data$\"",
"data", EscapeTrigraphs(CEscape(file_data.substr(i, kBytesPerLine))));
"data",
EscapeTrigraphs(
CEscape(file_data.substr(i, kBytesPerLine))));
}
printer->Print(
", $size$);\n",
@ -572,17 +604,26 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
"shutdownfilename", GlobalShutdownFileName(file_->name()));
printer->Outdent();
printer->Print(
"}\n"
"\n"
"\n");
PrintHandlingOptionalStaticInitializers(
file_, printer,
// With static initializers.
"// Force AddDescriptors() to be called at static initialization time.\n"
"struct StaticDescriptorInitializer_$filename$ {\n"
" StaticDescriptorInitializer_$filename$() {\n"
" $adddescriptorsname$();\n"
" }\n"
"} static_descriptor_initializer_$filename$_;\n"
"\n",
"} static_descriptor_initializer_$filename$_;\n",
// Without.
"GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
"void $adddescriptorsname$() {\n"
" ::google::protobuf::::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
" &$adddescriptorsname$_impl);\n"
"}\n",
// Vars.
"adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
"filename", FilenameIdentifier(file_->name()));
}

View File

@ -39,6 +39,7 @@
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@ -61,7 +62,7 @@ class FileGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit FileGenerator(const FileDescriptor* file,
const string& dllexport_decl);
const Options& options);
~FileGenerator();
void GenerateHeader(io::Printer* printer);
@ -85,7 +86,7 @@ class FileGenerator {
// E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
vector<string> package_parts_;
string dllexport_decl_;
const Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
};

View File

@ -78,11 +78,13 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// }
// FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
// __declspec(dllimport) depending on what is being compiled.
string dllexport_decl;
Options file_options;
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "dllexport_decl") {
dllexport_decl = options[i].second;
file_options.dllexport_decl = options[i].second;
} else if (options[i].first == "safe_boundary_check") {
file_options.safe_boundary_check = true;
} else {
*error = "Unknown generator option: " + options[i].first;
return false;
@ -95,7 +97,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
string basename = StripProto(file->name());
basename.append(".pb");
FileGenerator file_generator(file, dllexport_decl);
FileGenerator file_generator(file, file_options);
// Generate header.
{

View File

@ -33,10 +33,12 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <limits>
#include <map>
#include <vector>
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.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>
@ -105,6 +107,20 @@ string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
return result;
}
// Returns whether the provided descriptor has an extension. This includes its
// nested types.
bool HasExtension(const Descriptor* descriptor) {
if (descriptor->extension_count() > 0) {
return true;
}
for (int i = 0; i < descriptor->nested_type_count(); ++i) {
if (HasExtension(descriptor->nested_type(i))) {
return true;
}
}
return false;
}
} // namespace
const char kThickSeparator[] =
@ -132,7 +148,7 @@ string ClassName(const Descriptor* descriptor, bool qualified) {
string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
if (enum_descriptor->containing_type() == NULL) {
if (qualified) {
return DotsToColons(enum_descriptor->full_name());
return "::" + DotsToColons(enum_descriptor->full_name());
} else {
return enum_descriptor->name();
}
@ -243,10 +259,23 @@ const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
string DefaultValue(const FieldDescriptor* field) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
// gcc rejects the decimal form of kint32min and kint64min.
if (field->default_value_int32() == kint32min) {
// Make sure we are in a 2's complement system.
GOOGLE_COMPILE_ASSERT(kint32min == -0x80000000, kint32min_value_error);
return "-0x80000000";
}
return SimpleItoa(field->default_value_int32());
case FieldDescriptor::CPPTYPE_UINT32:
return SimpleItoa(field->default_value_uint32()) + "u";
case FieldDescriptor::CPPTYPE_INT64:
// See the comments for CPPTYPE_INT32.
if (field->default_value_int64() == kint64min) {
// Make sure we are in a 2's complement system.
GOOGLE_COMPILE_ASSERT(kint64min == GOOGLE_LONGLONG(-0x8000000000000000),
kint64min_value_error);
return "GOOGLE_LONGLONG(-0x8000000000000000)";
}
return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")";
case FieldDescriptor::CPPTYPE_UINT64:
return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
@ -292,7 +321,8 @@ string DefaultValue(const FieldDescriptor* field) {
ClassName(field->enum_type(), true),
field->default_value_enum()->number());
case FieldDescriptor::CPPTYPE_STRING:
return "\"" + EscapeTrigraphs(CEscape(field->default_value_string())) +
return "\"" + EscapeTrigraphs(
CEscape(field->default_value_string())) +
"\"";
case FieldDescriptor::CPPTYPE_MESSAGE:
return FieldMessageTypeName(field) + "::default_instance()";
@ -341,6 +371,67 @@ string EscapeTrigraphs(const string& to_escape) {
return StringReplace(to_escape, "?", "\\?", true);
}
bool StaticInitializersForced(const FileDescriptor* file) {
if (HasDescriptorMethods(file) || file->extension_count() > 0) {
return true;
}
for (int i = 0; i < file->message_type_count(); ++i) {
if (HasExtension(file->message_type(i))) {
return true;
}
}
return false;
}
void PrintHandlingOptionalStaticInitializers(
const FileDescriptor* file, io::Printer* printer,
const char* with_static_init, const char* without_static_init,
const char* var1, const string& val1,
const char* var2, const string& val2) {
map<string, string> vars;
if (var1) {
vars[var1] = val1;
}
if (var2) {
vars[var2] = val2;
}
PrintHandlingOptionalStaticInitializers(
vars, file, printer, with_static_init, without_static_init);
}
void PrintHandlingOptionalStaticInitializers(
const map<string, string>& vars, const FileDescriptor* file,
io::Printer* printer, const char* with_static_init,
const char* without_static_init) {
if (StaticInitializersForced(file)) {
printer->Print(vars, with_static_init);
} else {
printer->Print(vars, (string(
"#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n") +
without_static_init +
"#else\n" +
with_static_init +
"#endif\n").c_str());
}
}
static bool HasEnumDefinitions(const Descriptor* message_type) {
if (message_type->enum_type_count() > 0) return true;
for (int i = 0; i < message_type->nested_type_count(); ++i) {
if (HasEnumDefinitions(message_type->nested_type(i))) return true;
}
return false;
}
bool HasEnumDefinitions(const FileDescriptor* file) {
if (file->enum_type_count() > 0) return true;
for (int i = 0; i < file->message_type_count(); ++i) {
if (HasEnumDefinitions(file->message_type(i))) return true;
}
return false;
}
} // namespace cpp
} // namespace compiler
} // namespace protobuf

View File

@ -35,12 +35,18 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
#include <map>
#include <string>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
namespace google {
namespace protobuf {
namespace io {
class Printer;
}
namespace compiler {
namespace cpp {
@ -120,13 +126,17 @@ inline bool HasUnknownFields(const FileDescriptor *file) {
return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
}
// Does this file have any enum type definitions?
bool HasEnumDefinitions(const FileDescriptor* file);
// Does this file have generated parsing, serialization, and other
// standard methods for which reflection-based fallback implementations exist?
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?
// Do message classes in this file have descriptor and reflection methods?
inline bool HasDescriptorMethods(const FileDescriptor* file) {
return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
}
@ -150,6 +160,23 @@ inline bool HasFastArraySerialization(const FileDescriptor* file) {
return file->options().optimize_for() == FileOptions::SPEED;
}
// Returns whether we have to generate code with static initializers.
bool StaticInitializersForced(const FileDescriptor* file);
// Prints 'with_static_init' if static initializers have to be used for the
// provided file. Otherwise emits both 'with_static_init' and
// 'without_static_init' using #ifdef.
void PrintHandlingOptionalStaticInitializers(
const FileDescriptor* file, io::Printer* printer,
const char* with_static_init, const char* without_static_init,
const char* var1 = NULL, const string& val1 = "",
const char* var2 = NULL, const string& val2 = "");
void PrintHandlingOptionalStaticInitializers(
const map<string, string>& vars, const FileDescriptor* file,
io::Printer* printer, const char* with_static_init,
const char* without_static_init);
} // namespace cpp
} // namespace compiler

View File

@ -48,6 +48,7 @@
#include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h>
namespace google {
namespace protobuf {
namespace compiler {
@ -103,6 +104,13 @@ struct ExtensionRangeSorter {
}
};
// Returns true if the "required" restriction check should be ignored for the
// given field.
inline static bool ShouldIgnoreRequiredFieldCheck(
const FieldDescriptor* field) {
return false;
}
// Returns true if the message type has any required fields. If it doesn't,
// we can optimize out calls to its IsInitialized() method.
//
@ -129,7 +137,8 @@ static bool HasRequiredFields(
if (field->is_required()) {
return true;
}
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
!ShouldIgnoreRequiredFieldCheck(field)) {
if (HasRequiredFields(field->message_type(), already_seen)) {
return true;
}
@ -280,11 +289,11 @@ void OptimizePadding(vector<const FieldDescriptor*>* fields) {
// ===================================================================
MessageGenerator::MessageGenerator(const Descriptor* descriptor,
const string& dllexport_decl)
const Options& options)
: descriptor_(descriptor),
classname_(ClassName(descriptor, false)),
dllexport_decl_(dllexport_decl),
field_generators_(descriptor),
options_(options),
field_generators_(descriptor, options),
nested_generators_(new scoped_ptr<MessageGenerator>[
descriptor->nested_type_count()]),
enum_generators_(new scoped_ptr<EnumGenerator>[
@ -294,17 +303,17 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
for (int i = 0; i < descriptor->nested_type_count(); i++) {
nested_generators_[i].reset(
new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
new MessageGenerator(descriptor->nested_type(i), options));
}
for (int i = 0; i < descriptor->enum_type_count(); i++) {
enum_generators_[i].reset(
new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
new EnumGenerator(descriptor->enum_type(i), options));
}
for (int i = 0; i < descriptor->extension_count(); i++) {
extension_generators_[i].reset(
new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
new ExtensionGenerator(descriptor->extension(i), options));
}
}
@ -349,7 +358,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
PrintFieldComment(printer, field);
map<string, string> vars;
SetCommonFieldVariables(field, &vars);
SetCommonFieldVariables(field, &vars, options_);
vars["constant_name"] = FieldConstantName(field);
if (field->is_repeated()) {
@ -386,7 +395,7 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
PrintFieldComment(printer, field);
map<string, string> vars;
SetCommonFieldVariables(field, &vars);
SetCommonFieldVariables(field, &vars, options_);
// Generate has_$name$() or $name$_size().
if (field->is_repeated()) {
@ -446,10 +455,10 @@ GenerateClassDefinition(io::Printer* printer) {
map<string, string> vars;
vars["classname"] = classname_;
vars["field_count"] = SimpleItoa(descriptor_->field_count());
if (dllexport_decl_.empty()) {
if (options_.dllexport_decl.empty()) {
vars["dllexport"] = "";
} else {
vars["dllexport"] = dllexport_decl_ + " ";
vars["dllexport"] = options_.dllexport_decl + " ";
}
vars["superclass"] = SuperClassName(descriptor_);
@ -493,6 +502,20 @@ GenerateClassDefinition(io::Printer* printer) {
"static const $classname$& default_instance();\n"
"\n");
if (!StaticInitializersForced(descriptor_->file())) {
printer->Print(vars,
"#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
"// Returns the internal default instance pointer. This function can\n"
"// return NULL thus should not be used by the user. This is intended\n"
"// for Protobuf internal code. Please use default_instance() declared\n"
"// above instead.\n"
"static inline const $classname$* internal_default_instance() {\n"
" return default_instance_;\n"
"}\n"
"#endif\n"
"\n");
}
printer->Print(vars,
"void Swap($classname$* other);\n"
@ -592,6 +615,7 @@ GenerateClassDefinition(io::Printer* printer) {
printer->Print(" private:\n");
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
if (!descriptor_->field(i)->is_repeated()) {
printer->Print(
@ -660,11 +684,17 @@ GenerateClassDefinition(io::Printer* printer) {
// Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
// friends so that they can access private static variables like
// default_instance_ and reflection_.
printer->Print(
PrintHandlingOptionalStaticInitializers(
descriptor_->file(), printer,
// With static initializers.
"friend void $dllexport_decl$ $adddescriptorsname$();\n",
"dllexport_decl", dllexport_decl_,
// Without.
"friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
// Vars.
"dllexport_decl", options_.dllexport_decl,
"adddescriptorsname",
GlobalAddDescriptorsName(descriptor_->file()->name()));
printer->Print(
"friend void $assigndescriptorsname$();\n"
"friend void $shutdownfilename$();\n"
@ -753,9 +783,11 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
printer->Print(vars,
" -1,\n");
}
printer->Print(
" ::google::protobuf::DescriptorPool::generated_pool(),\n");
printer->Print(vars,
" ::google::protobuf::MessageFactory::generated_factory(),\n");
printer->Print(vars,
" ::google::protobuf::DescriptorPool::generated_pool(),\n"
" ::google::protobuf::MessageFactory::generated_factory(),\n"
" sizeof($classname$));\n");
// Handle nested types.
@ -784,6 +816,13 @@ GenerateTypeRegistrations(io::Printer* printer) {
void MessageGenerator::
GenerateDefaultInstanceAllocator(io::Printer* printer) {
// Construct the default instances of all fields, as they will be used
// when creating the default instance of the entire message.
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i))
.GenerateDefaultInstanceAllocator(printer);
}
// Construct the default instance. We can't call InitAsDefaultInstance() yet
// because we need to make sure all default instances that this one might
// depend on are constructed first.
@ -827,6 +866,12 @@ GenerateShutdownCode(io::Printer* printer) {
"classname", classname_);
}
// Handle default instances of fields.
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i))
.GenerateShutdownCode(printer);
}
// Handle nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateShutdownCode(printer);
@ -981,8 +1026,12 @@ GenerateSharedDestructorCode(io::Printer* printer) {
.GenerateDestructorCode(printer);
}
printer->Print(
"if (this != default_instance_) {\n");
PrintHandlingOptionalStaticInitializers(
descriptor_->file(), printer,
// With static initializers.
"if (this != default_instance_) {\n",
// Without.
"if (this != &default_instance()) {\n");
// We need to delete all embedded messages.
// TODO(kenton): If we make unset messages point at default instances
@ -1034,8 +1083,14 @@ GenerateStructors(io::Printer* printer) {
if (!field->is_repeated() &&
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
printer->Print(
PrintHandlingOptionalStaticInitializers(
descriptor_->file(), printer,
// With static initializers.
" $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
// Without.
" $name$_ = const_cast< $type$*>(\n"
" $type$::internal_default_instance());\n",
// Vars.
"name", FieldName(field),
"type", FieldMessageTypeName(field));
}
@ -1093,8 +1148,20 @@ GenerateStructors(io::Printer* printer) {
}
printer->Print(
"const $classname$& $classname$::default_instance() {\n"
" if (default_instance_ == NULL) $adddescriptorsname$();"
"const $classname$& $classname$::default_instance() {\n",
"classname", classname_);
PrintHandlingOptionalStaticInitializers(
descriptor_->file(), printer,
// With static initializers.
" if (default_instance_ == NULL) $adddescriptorsname$();\n",
// Without.
" $adddescriptorsname$();\n",
// Vars.
"adddescriptorsname",
GlobalAddDescriptorsName(descriptor_->file()->name()));
printer->Print(
" return *default_instance_;\n"
"}\n"
"\n"
@ -1106,7 +1173,6 @@ GenerateStructors(io::Printer* printer) {
"classname", classname_,
"adddescriptorsname",
GlobalAddDescriptorsName(descriptor_->file()->name()));
}
void MessageGenerator::
@ -1377,11 +1443,22 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// Special-case MessageSet.
printer->Print(
"bool $classname$::MergePartialFromCodedStream(\n"
" ::google::protobuf::io::CodedInputStream* input) {\n"
" return _extensions_.ParseMessageSet(input, default_instance_,\n"
" mutable_unknown_fields());\n"
"}\n",
" ::google::protobuf::io::CodedInputStream* input) {\n",
"classname", classname_);
PrintHandlingOptionalStaticInitializers(
descriptor_->file(), printer,
// With static initializers.
" return _extensions_.ParseMessageSet(input, default_instance_,\n"
" mutable_unknown_fields());\n",
// Without.
" return _extensions_.ParseMessageSet(input, &default_instance(),\n"
" mutable_unknown_fields());\n",
// Vars.
"classname", classname_);
printer->Print(
"}\n");
return;
}
@ -1541,12 +1618,21 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
}
printer->Print(") {\n");
if (HasUnknownFields(descriptor_->file())) {
printer->Print(
PrintHandlingOptionalStaticInitializers(
descriptor_->file(), printer,
// With static initializers.
" DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
" mutable_unknown_fields()));\n",
// Without.
" DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
" mutable_unknown_fields()));\n");
} else {
printer->Print(
" DO_(_extensions_.ParseField(tag, input, default_instance_));\n");
PrintHandlingOptionalStaticInitializers(
descriptor_->file(), printer,
// With static initializers.
" DO_(_extensions_.ParseField(tag, input, default_instance_));\n",
// Without.
" DO_(_extensions_.ParseField(tag, input, &default_instance()));\n");
}
printer->Print(
" continue;\n"
@ -1897,6 +1983,7 @@ GenerateIsInitialized(io::Printer* printer) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
!ShouldIgnoreRequiredFieldCheck(field) &&
HasRequiredFields(field->message_type())) {
if (field->is_repeated()) {
printer->Print(

View File

@ -38,6 +38,7 @@
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@ -57,7 +58,7 @@ class MessageGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit MessageGenerator(const Descriptor* descriptor,
const string& dllexport_decl);
const Options& options);
~MessageGenerator();
// Header stuff.
@ -153,7 +154,7 @@ class MessageGenerator {
const Descriptor* descriptor_;
string classname_;
string dllexport_decl_;
Options options_;
FieldGeneratorMap field_generators_;
scoped_array<scoped_ptr<MessageGenerator> > nested_generators_;
scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;

View File

@ -45,8 +45,9 @@ namespace cpp {
namespace {
void SetMessageVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, variables);
map<string, string>* variables,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = FieldMessageTypeName(descriptor);
(*variables)["stream_writer"] = (*variables)["declared_type"] +
(HasFastArraySerialization(descriptor->message_type()->file()) ?
@ -59,9 +60,10 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// ===================================================================
MessageFieldGenerator::
MessageFieldGenerator(const FieldDescriptor* descriptor)
MessageFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetMessageVariables(descriptor, &variables_);
SetMessageVariables(descriptor, &variables_, options);
}
MessageFieldGenerator::~MessageFieldGenerator() {}
@ -76,14 +78,23 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
"inline const $type$& $name$() const$deprecation$;\n"
"inline $type$* mutable_$name$()$deprecation$;\n"
"inline $type$* release_$name$()$deprecation$;\n");
"inline $type$* release_$name$()$deprecation$;\n"
"inline void set_allocated_$name$($type$* $name$)$deprecation$;\n");
}
void MessageFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const $type$& $classname$::$name$() const {\n"
" return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n"
"inline const $type$& $classname$::$name$() const {\n");
PrintHandlingOptionalStaticInitializers(
variables_, descriptor_->file(), printer,
// With static initializers.
" return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
// Without.
" return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
printer->Print(variables_,
"}\n"
"inline $type$* $classname$::mutable_$name$() {\n"
" set_has_$name$();\n"
@ -95,6 +106,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" $type$* temp = $name$_;\n"
" $name$_ = NULL;\n"
" return temp;\n"
"}\n"
"inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
" delete $name$_;\n"
" $name$_ = $name$;\n"
" if ($name$) {\n"
" set_has_$name$();\n"
" } else {\n"
" clear_has_$name$();\n"
" }\n"
"}\n");
}
@ -159,9 +179,10 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
RepeatedMessageFieldGenerator::
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetMessageVariables(descriptor, &variables_);
SetMessageVariables(descriptor, &variables_, options);
}
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
@ -189,7 +210,7 @@ void RepeatedMessageFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const $type$& $classname$::$name$(int index) const {\n"
" return $name$_.Get(index);\n"
" return $name$_.$cppget$(index);\n"
"}\n"
"inline $type$* $classname$::mutable_$name$(int index) {\n"
" return $name$_.Mutable(index);\n"

View File

@ -46,7 +46,8 @@ namespace cpp {
class MessageFieldGenerator : public FieldGenerator {
public:
explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
explicit MessageFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~MessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
@ -71,7 +72,8 @@ class MessageFieldGenerator : public FieldGenerator {
class RepeatedMessageFieldGenerator : public FieldGenerator {
public:
explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~RepeatedMessageFieldGenerator();
// implements FieldGenerator ---------------------------------------

View File

@ -0,0 +1,58 @@
// 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: rennie@google.com (Jeffrey Rennie)
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {
// Generator options:
struct Options {
Options() : safe_boundary_check(false) {
}
string dllexport_decl;
bool safe_boundary_check;
};
} // namespace cpp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__

View File

@ -80,8 +80,9 @@ int FixedSize(FieldDescriptor::Type type) {
}
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, variables);
map<string, string>* variables,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
(*variables)["default"] = DefaultValue(descriptor);
(*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
@ -99,9 +100,10 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
// ===================================================================
PrimitiveFieldGenerator::
PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetPrimitiveVariables(descriptor, &variables_);
SetPrimitiveVariables(descriptor, &variables_, options);
}
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
@ -190,9 +192,10 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
RepeatedPrimitiveFieldGenerator::
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetPrimitiveVariables(descriptor, &variables_);
SetPrimitiveVariables(descriptor, &variables_, options);
if (descriptor->options().packed()) {
variables_["packed_reader"] = "ReadPackedPrimitive";
@ -366,7 +369,9 @@ GenerateByteSize(io::Printer* printer) const {
" total_size += $tag_size$ +\n"
" ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
"}\n"
"GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
"_$name$_cached_byte_size_ = data_size;\n"
"GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
"total_size += data_size;\n");
} else {
printer->Print(variables_,

View File

@ -46,7 +46,8 @@ namespace cpp {
class PrimitiveFieldGenerator : public FieldGenerator {
public:
explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~PrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
@ -71,7 +72,8 @@ class PrimitiveFieldGenerator : public FieldGenerator {
class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
public:
explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~RepeatedPrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------

View File

@ -43,14 +43,14 @@ namespace compiler {
namespace cpp {
ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
const string& dllexport_decl)
const Options& options)
: descriptor_(descriptor) {
vars_["classname"] = descriptor_->name();
vars_["full_name"] = descriptor_->full_name();
if (dllexport_decl.empty()) {
if (options.dllexport_decl.empty()) {
vars_["dllexport"] = "";
} else {
vars_["dllexport"] = dllexport_decl + " ";
vars_["dllexport"] = options.dllexport_decl + " ";
}
}

View File

@ -38,6 +38,7 @@
#include <map>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
namespace google {
@ -55,7 +56,7 @@ class ServiceGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit ServiceGenerator(const ServiceDescriptor* descriptor,
const string& dllexport_decl);
const Options& options);
~ServiceGenerator();
// Header stuff.

View File

@ -46,11 +46,14 @@ namespace cpp {
namespace {
void SetStringVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, variables);
map<string, string>* variables,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["default"] = DefaultValue(descriptor);
(*variables)["default_length"] =
SimpleItoa(descriptor->default_value_string().length());
(*variables)["default_variable"] = descriptor->default_value_string().empty()
? "::google::protobuf::internal::kEmptyString"
? "&::google::protobuf::internal::kEmptyString"
: "_default_" + FieldName(descriptor) + "_";
(*variables)["pointer_type"] =
descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
@ -61,9 +64,10 @@ void SetStringVariables(const FieldDescriptor* descriptor,
// ===================================================================
StringFieldGenerator::
StringFieldGenerator(const FieldDescriptor* descriptor)
StringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetStringVariables(descriptor, &variables_);
SetStringVariables(descriptor, &variables_, options);
}
StringFieldGenerator::~StringFieldGenerator() {}
@ -72,7 +76,7 @@ void StringFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_, "::std::string* $name$_;\n");
if (!descriptor_->default_value_string().empty()) {
printer->Print(variables_, "static const ::std::string $default_variable$;\n");
printer->Print(variables_, "static ::std::string* $default_variable$;\n");
}
}
@ -109,7 +113,9 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"inline void set_$name$(const $pointer_type$* value, size_t size)"
"$deprecation$;\n"
"inline ::std::string* mutable_$name$()$deprecation$;\n"
"inline ::std::string* release_$name$()$deprecation$;\n");
"inline ::std::string* release_$name$()$deprecation$;\n"
"inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
if (descriptor_->options().ctype() != FieldOptions::STRING) {
printer->Outdent();
@ -126,14 +132,14 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
"}\n"
"inline void $classname$::set_$name$(const ::std::string& value) {\n"
" set_has_$name$();\n"
" if ($name$_ == &$default_variable$) {\n"
" if ($name$_ == $default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
"}\n"
"inline void $classname$::set_$name$(const char* value) {\n"
" set_has_$name$();\n"
" if ($name$_ == &$default_variable$) {\n"
" if ($name$_ == $default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
@ -141,20 +147,20 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
"inline "
"void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
" set_has_$name$();\n"
" if ($name$_ == &$default_variable$) {\n"
" if ($name$_ == $default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
"}\n"
"inline ::std::string* $classname$::mutable_$name$() {\n"
" set_has_$name$();\n"
" if ($name$_ == &$default_variable$) {\n");
" if ($name$_ == $default_variable$) {\n");
if (descriptor_->default_value_string().empty()) {
printer->Print(variables_,
" $name$_ = new ::std::string;\n");
} else {
printer->Print(variables_,
" $name$_ = new ::std::string($default_variable$);\n");
" $name$_ = new ::std::string(*$default_variable$);\n");
}
printer->Print(variables_,
" }\n"
@ -162,21 +168,34 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
"}\n"
"inline ::std::string* $classname$::release_$name$() {\n"
" clear_has_$name$();\n"
" if ($name$_ == &$default_variable$) {\n"
" if ($name$_ == $default_variable$) {\n"
" return NULL;\n"
" } else {\n"
" ::std::string* temp = $name$_;\n"
" $name$_ = const_cast< ::std::string*>(&$default_variable$);\n"
" $name$_ = const_cast< ::std::string*>($default_variable$);\n"
" return temp;\n"
" }\n"
"}\n"
"inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
" if ($name$_ != $default_variable$) {\n"
" delete $name$_;\n"
" }\n"
" if ($name$) {\n"
" set_has_$name$();\n"
" $name$_ = $name$;\n"
" } else {\n"
" clear_has_$name$();\n"
" $name$_ = const_cast< ::std::string*>($default_variable$);\n"
" }\n"
"}\n");
}
void StringFieldGenerator::
GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
if (!descriptor_->default_value_string().empty()) {
// Initialized in GenerateDefaultInstanceAllocator.
printer->Print(variables_,
"const ::std::string $classname$::$default_variable$($default$);\n");
"::std::string* $classname$::$default_variable$ = NULL;\n");
}
}
@ -184,13 +203,13 @@ void StringFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
if (descriptor_->default_value_string().empty()) {
printer->Print(variables_,
"if ($name$_ != &$default_variable$) {\n"
"if ($name$_ != $default_variable$) {\n"
" $name$_->clear();\n"
"}\n");
} else {
printer->Print(variables_,
"if ($name$_ != &$default_variable$) {\n"
" $name$_->assign($default_variable$);\n"
"if ($name$_ != $default_variable$) {\n"
" $name$_->assign(*$default_variable$);\n"
"}\n");
}
}
@ -208,17 +227,34 @@ GenerateSwappingCode(io::Printer* printer) const {
void StringFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
printer->Print(variables_,
"$name$_ = const_cast< ::std::string*>(&$default_variable$);\n");
"$name$_ = const_cast< ::std::string*>($default_variable$);\n");
}
void StringFieldGenerator::
GenerateDestructorCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($name$_ != &$default_variable$) {\n"
"if ($name$_ != $default_variable$) {\n"
" delete $name$_;\n"
"}\n");
}
void StringFieldGenerator::
GenerateDefaultInstanceAllocator(io::Printer* printer) const {
if (!descriptor_->default_value_string().empty()) {
printer->Print(variables_,
"$classname$::$default_variable$ =\n"
" new ::std::string($default$, $default_length$);\n");
}
}
void StringFieldGenerator::
GenerateShutdownCode(io::Printer* printer) const {
if (!descriptor_->default_value_string().empty()) {
printer->Print(variables_,
"delete $classname$::$default_variable$;\n");
}
}
void StringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
@ -273,9 +309,10 @@ GenerateByteSize(io::Printer* printer) const {
// ===================================================================
RepeatedStringFieldGenerator::
RepeatedStringFieldGenerator(const FieldDescriptor* descriptor)
RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetStringVariables(descriptor, &variables_);
SetStringVariables(descriptor, &variables_, options);
}
RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
@ -328,7 +365,7 @@ void RepeatedStringFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const ::std::string& $classname$::$name$(int index) const {\n"
" return $name$_.Get(index);\n"
" return $name$_.$cppget$(index);\n"
"}\n"
"inline ::std::string* $classname$::mutable_$name$(int index) {\n"
" return $name$_.Mutable(index);\n"
@ -398,7 +435,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
printer->Print(variables_,
"::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
" this->$name$(0).data(), this->$name$(0).length(),\n"
" this->$name$(this->$name$_size() - 1).data(),\n"
" this->$name$(this->$name$_size() - 1).length(),\n"
" ::google::protobuf::internal::WireFormat::PARSE);\n");
}
}

View File

@ -46,7 +46,8 @@ namespace cpp {
class StringFieldGenerator : public FieldGenerator {
public:
explicit StringFieldGenerator(const FieldDescriptor* descriptor);
explicit StringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~StringFieldGenerator();
// implements FieldGenerator ---------------------------------------
@ -59,6 +60,8 @@ class StringFieldGenerator : public FieldGenerator {
void GenerateSwappingCode(io::Printer* printer) const;
void GenerateConstructorCode(io::Printer* printer) const;
void GenerateDestructorCode(io::Printer* printer) const;
void GenerateDefaultInstanceAllocator(io::Printer* printer) const;
void GenerateShutdownCode(io::Printer* printer) const;
void GenerateMergeFromCodedStream(io::Printer* printer) const;
void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
@ -73,7 +76,8 @@ class StringFieldGenerator : public FieldGenerator {
class RepeatedStringFieldGenerator : public FieldGenerator {
public:
explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor);
explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~RepeatedStringFieldGenerator();
// implements FieldGenerator ---------------------------------------

View File

@ -103,9 +103,19 @@ message TestConflictingSymbolNames {
message DO {}
optional DO do = 32;
// Some template parameter names for extensions.
optional int32 field_type = 33;
optional bool is_packed = 34;
extensions 1000 to max;
}
message TestConflictingSymbolNamesExtension {
extend TestConflictingSymbolNames {
repeated int32 repeated_int32_ext = 20423638 [packed=true];
}
}
message DummyMessage {}
service TestConflictingMethodNames {

View File

@ -44,6 +44,8 @@
// correctly and produces the interfaces we expect, which is why this test
// is written this way.
#include <google/protobuf/compiler/cpp/cpp_unittest.h>
#include <vector>
#include <google/protobuf/unittest.pb.h>
@ -64,7 +66,7 @@
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/stubs/stl_util-inl.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@ -74,6 +76,8 @@ namespace cpp {
// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
namespace cpp_unittest {
namespace protobuf_unittest = ::protobuf_unittest;
class MockErrorCollector : public MultiFileErrorCollector {
public:
@ -174,6 +178,15 @@ TEST(GeneratedMessageTest, Trigraph) {
EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph());
}
TEST(GeneratedMessageTest, ExtremeSmallIntegerDefault) {
const unittest::TestExtremeDefaultValues& extreme_default =
unittest::TestExtremeDefaultValues::default_instance();
EXPECT_EQ(-0x80000000, kint32min);
EXPECT_EQ(GOOGLE_LONGLONG(-0x8000000000000000), kint64min);
EXPECT_EQ(kint32min, extreme_default.really_small_int32());
EXPECT_EQ(kint64min, extreme_default.really_small_int64());
}
TEST(GeneratedMessageTest, Accessors) {
// Set every field to a unique value then go back and check all those
// values.
@ -202,6 +215,13 @@ TEST(GeneratedMessageTest, MutableStringDefault) {
EXPECT_EQ("hello", *message.mutable_default_string());
}
TEST(GeneratedMessageTest, StringDefaults) {
unittest::TestExtremeDefaultValues message;
// Check if '\000' can be used in default string value.
EXPECT_EQ(string("hel\000lo", 6), message.string_with_zero());
EXPECT_EQ(string("wor\000ld", 6), message.bytes_with_zero());
}
TEST(GeneratedMessageTest, ReleaseString) {
// Check that release_foo() starts out NULL, and gives us a value
// that we can delete after it's been set.
@ -244,6 +264,49 @@ TEST(GeneratedMessageTest, ReleaseMessage) {
EXPECT_FALSE(message.has_optional_nested_message());
}
TEST(GeneratedMessageTest, SetAllocatedString) {
// Check that set_allocated_foo() works for strings.
unittest::TestAllTypes message;
EXPECT_FALSE(message.has_optional_string());
const string kHello("hello");
message.set_optional_string(kHello);
EXPECT_TRUE(message.has_optional_string());
message.set_allocated_optional_string(NULL);
EXPECT_FALSE(message.has_optional_string());
EXPECT_EQ("", message.optional_string());
message.set_allocated_optional_string(new string(kHello));
EXPECT_TRUE(message.has_optional_string());
EXPECT_EQ(kHello, message.optional_string());
}
TEST(GeneratedMessageTest, SetAllocatedMessage) {
// Check that set_allocated_foo() can be called in all cases.
unittest::TestAllTypes message;
EXPECT_FALSE(message.has_optional_nested_message());
message.mutable_optional_nested_message()->set_bb(1);
EXPECT_TRUE(message.has_optional_nested_message());
message.set_allocated_optional_nested_message(NULL);
EXPECT_FALSE(message.has_optional_nested_message());
EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
&message.optional_nested_message());
message.mutable_optional_nested_message()->set_bb(1);
unittest::TestAllTypes::NestedMessage* nest =
message.release_optional_nested_message();
ASSERT_TRUE(nest != NULL);
EXPECT_FALSE(message.has_optional_nested_message());
message.set_allocated_optional_nested_message(nest);
EXPECT_TRUE(message.has_optional_nested_message());
EXPECT_EQ(1, message.optional_nested_message().bb());
}
TEST(GeneratedMessageTest, Clear) {
// Set every field to a unique value, clear the message, then check that
// it is cleared.
@ -318,7 +381,6 @@ TEST(GeneratedMessageTest, StringCharStarLength) {
EXPECT_EQ("wx", message.repeated_string(0));
}
TEST(GeneratedMessageTest, CopyFrom) {
unittest::TestAllTypes message1, message2;
@ -331,7 +393,6 @@ TEST(GeneratedMessageTest, CopyFrom) {
TestUtil::ExpectAllFieldsSet(message2);
}
TEST(GeneratedMessageTest, SwapWithEmpty) {
unittest::TestAllTypes message1, message2;
TestUtil::SetAllFields(&message1);
@ -430,6 +491,8 @@ TEST(GeneratedMessageTest, CopyAssignmentOperator) {
TestUtil::ExpectAllFieldsSet(message2);
}
#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
!defined(GOOGLE_PROTOBUF_NO_RTTI)
TEST(GeneratedMessageTest, UpcastCopyFrom) {
// Test the CopyFrom method that takes in the generic const Message&
// parameter.
@ -442,6 +505,7 @@ TEST(GeneratedMessageTest, UpcastCopyFrom) {
TestUtil::ExpectAllFieldsSet(message2);
}
#endif
#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
@ -493,7 +557,9 @@ TEST(GeneratedMessageTest, NonEmptyMergeFrom) {
TestUtil::ExpectAllFieldsSet(message1);
}
#ifdef GTEST_HAS_DEATH_TEST
#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
!defined(GOOGLE_PROTOBUF_NO_RTTI)
#ifdef PROTOBUF_HAS_DEATH_TEST
TEST(GeneratedMessageTest, MergeFromSelf) {
unittest::TestAllTypes message;
@ -502,7 +568,8 @@ TEST(GeneratedMessageTest, MergeFromSelf) {
"&from");
}
#endif // GTEST_HAS_DEATH_TEST
#endif // PROTOBUF_HAS_DEATH_TEST
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS || !GOOGLE_PROTOBUF_NO_RTTI
// Test the generated SerializeWithCachedSizesToArray(),
TEST(GeneratedMessageTest, SerializationToArray) {
@ -695,6 +762,13 @@ TEST(GeneratedMessageTest, TestConflictingSymbolNames) {
message.set_friend_(5);
EXPECT_EQ(5, message.friend_());
// Instantiate extension template functions to test conflicting template
// parameter names.
typedef protobuf_unittest::TestConflictingSymbolNamesExtension ExtensionMessage;
message.AddExtension(ExtensionMessage::repeated_int32_ext, 123);
EXPECT_EQ(123,
message.GetExtension(ExtensionMessage::repeated_int32_ext, 0));
}
#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
@ -869,11 +943,10 @@ TEST(GeneratedEnumTest, MinAndMax) {
EXPECT_NE(null_pointer, &unittest::ForeignEnum_MAX);
EXPECT_NE(null_pointer, &unittest::ForeignEnum_ARRAYSIZE);
// Make sure we can use _MIN, _MAX and _ARRAYSIZE as switch cases.
// Make sure we can use _MIN and _MAX as switch cases.
switch (unittest::SPARSE_A) {
case unittest::TestSparseEnum_MIN:
case unittest::TestSparseEnum_MAX:
case unittest::TestSparseEnum_ARRAYSIZE:
break;
default:
break;
@ -1130,7 +1203,7 @@ TEST_F(GeneratedServiceTest, CallMethod) {
TEST_F(GeneratedServiceTest, CallMethodTypeFailure) {
// Verify death if we call Foo() with Bar's message types.
#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
EXPECT_DEBUG_DEATH(
mock_service_.CallMethod(foo_, &mock_controller_,
&foo_request_, &bar_response_, done_.get()),
@ -1141,7 +1214,7 @@ TEST_F(GeneratedServiceTest, CallMethodTypeFailure) {
mock_service_.CallMethod(foo_, &mock_controller_,
&bar_request_, &foo_response_, done_.get()),
"dynamic_cast");
#endif // GTEST_HAS_DEATH_TEST
#endif // PROTOBUF_HAS_DEATH_TEST
}
TEST_F(GeneratedServiceTest, GetPrototypes) {

View File

@ -0,0 +1,51 @@
// 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.
// This header declares the namespace google::protobuf::protobuf_unittest in order to expose
// any problems with the generated class names. We use this header to ensure
// unittest.cc will declare the namespace prior to other includes, while obeying
// normal include ordering.
//
// When generating a class name of "foo.Bar" we must ensure we prefix the class
// name with "::", in case the namespace google::protobuf::foo exists. We intentionally
// trigger that case here by declaring google::protobuf::protobuf_unittest.
//
// See ClassName in helpers.h for more details.
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
namespace google {
namespace protobuf {
namespace protobuf_unittest {}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__

View File

@ -280,8 +280,9 @@ class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree {
string virtual_path;
string disk_path;
inline Mapping(const string& virtual_path, const string& disk_path)
: virtual_path(virtual_path), disk_path(disk_path) {}
inline Mapping(const string& virtual_path_param,
const string& disk_path_param)
: virtual_path(virtual_path_param), disk_path(disk_path_param) {}
};
vector<Mapping> mappings_;

View File

@ -0,0 +1,236 @@
// 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/java/java_doc_comment.h>
#include <vector>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
string EscapeJavadoc(const string& input) {
string result;
result.reserve(input.size() * 2);
char prev = '*';
for (string::size_type i = 0; i < input.size(); i++) {
char c = input[i];
switch (c) {
case '*':
// Avoid "/*".
if (prev == '/') {
result.append("&#42;");
} else {
result.push_back(c);
}
break;
case '/':
// Avoid "*/".
if (prev == '*') {
result.append("&#47;");
} else {
result.push_back(c);
}
break;
case '@':
// "{@" starts Javadoc markup.
if (prev == '{') {
result.append("&#64;");
} else {
result.push_back(c);
}
break;
case '<':
// Avoid interpretation as HTML.
result.append("&lt;");
break;
case '>':
// Avoid interpretation as HTML.
result.append("&gt;");
break;
case '&':
// Avoid interpretation as HTML.
result.append("&amp;");
break;
case '\\':
// Java interprets Unicode escape sequences anywhere!
result.append("&#92;");
break;
default:
result.push_back(c);
break;
}
prev = c;
}
return result;
}
static void WriteDocCommentBodyForLocation(
io::Printer* printer, const SourceLocation& location) {
string comments = location.leading_comments.empty() ?
location.trailing_comments : location.leading_comments;
if (!comments.empty()) {
// TODO(kenton): Ideally we should parse the comment text as Markdown and
// write it back as HTML, but this requires a Markdown parser. For now
// we just use <pre> to get fixed-width text formatting.
// If the comment itself contains block comment start or end markers,
// HTML-escape them so that they don't accidentally close the doc comment.
comments = EscapeJavadoc(comments);
vector<string> lines;
SplitStringAllowEmpty(comments, "\n", &lines);
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
printer->Print(
" *\n"
" * <pre>\n");
for (int i = 0; i < lines.size(); i++) {
// Most lines should start with a space. Watch out for lines that start
// with a /, since putting that right after the leading asterisk will
// close the comment.
if (!lines[i].empty() && lines[i][0] == '/') {
printer->Print(" * $line$\n", "line", lines[i]);
} else {
printer->Print(" *$line$\n", "line", lines[i]);
}
}
printer->Print(" * </pre>\n");
}
}
template <typename DescriptorType>
static void WriteDocCommentBody(
io::Printer* printer, const DescriptorType* descriptor) {
SourceLocation location;
if (descriptor->GetSourceLocation(&location)) {
WriteDocCommentBodyForLocation(printer, location);
}
}
static string FirstLineOf(const string& value) {
string result = value;
string::size_type pos = result.find_first_of('\n');
if (pos != string::npos) {
result.erase(pos);
}
// If line ends in an opening brace, make it "{ ... }" so it looks nice.
if (!result.empty() && result[result.size() - 1] == '{') {
result.append(" ... }");
}
return result;
}
void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) {
printer->Print(
"/**\n"
" * Protobuf type {@code $fullname$}\n",
"fullname", EscapeJavadoc(message->full_name()));
WriteDocCommentBody(printer, message);
printer->Print(" */\n");
}
void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) {
// In theory we should have slightly different comments for setters, getters,
// etc., but in practice everyone already knows the difference between these
// so it's redundant information.
// We use the field declaration as the first line of the comment, e.g.:
// optional string foo = 5;
// This communicates a lot of information about the field in a small space.
// If the field is a group, the debug string might end with {.
printer->Print(
"/**\n"
" * <code>$def$</code>\n",
"def", EscapeJavadoc(FirstLineOf(field->DebugString())));
WriteDocCommentBody(printer, field);
printer->Print(" */\n");
}
void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) {
printer->Print(
"/**\n"
" * Protobuf enum {@code $fullname$}\n",
"fullname", EscapeJavadoc(enum_->full_name()));
WriteDocCommentBody(printer, enum_);
printer->Print(" */\n");
}
void WriteEnumValueDocComment(io::Printer* printer,
const EnumValueDescriptor* value) {
printer->Print(
"/**\n"
" * <code>$def$</code>\n",
"def", EscapeJavadoc(FirstLineOf(value->DebugString())));
WriteDocCommentBody(printer, value);
printer->Print(" */\n");
}
void WriteServiceDocComment(io::Printer* printer,
const ServiceDescriptor* service) {
printer->Print(
"/**\n"
" * Protobuf service {@code $fullname$}\n",
"fullname", EscapeJavadoc(service->full_name()));
WriteDocCommentBody(printer, service);
printer->Print(" */\n");
}
void WriteMethodDocComment(io::Printer* printer,
const MethodDescriptor* method) {
printer->Print(
"/**\n"
" * <code>$def$</code>\n",
"def", EscapeJavadoc(FirstLineOf(method->DebugString())));
WriteDocCommentBody(printer, method);
printer->Print(" */\n");
}
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,69 @@
// 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_DOC_COMMENT_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
namespace io {
class Printer; // printer.h
}
}
namespace protobuf {
namespace compiler {
namespace java {
void WriteMessageDocComment(io::Printer* printer, const Descriptor* message);
void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field);
void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_);
void WriteEnumValueDocComment(io::Printer* printer,
const EnumValueDescriptor* value);
void WriteServiceDocComment(io::Printer* printer,
const ServiceDescriptor* service);
void WriteMethodDocComment(io::Printer* printer,
const MethodDescriptor* method);
// Exposed for testing only.
LIBPROTOC_EXPORT string EscapeJavadoc(const string& input);
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__

View File

@ -0,0 +1,66 @@
// 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/java/java_doc_comment.h>
#include <gtest/gtest.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
namespace {
TEST(JavaDocCommentTest, Escaping) {
EXPECT_EQ("foo /&#42; bar *&#47; baz", EscapeJavadoc("foo /* bar */ baz"));
EXPECT_EQ("foo /&#42;&#47; baz", EscapeJavadoc("foo /*/ baz"));
EXPECT_EQ("{&#64;foo}", EscapeJavadoc("{@foo}"));
EXPECT_EQ("&lt;i&gt;&amp;&lt;/i&gt;", EscapeJavadoc("<i>&</i>"));
EXPECT_EQ("foo&#92;u1234bar", EscapeJavadoc("foo\\u1234bar"));
}
// TODO(kenton): It's hard to write a robust test of the doc comments -- we
// can only really compare the output against a golden value, which is a
// fairly tedious and fragile testing strategy. If we want to go that route,
// it probably makes sense to bite the bullet and write a test that compares
// the whole generated output for unittest.proto against a golden value, with
// a very simple script that can be run to regenerate it with the latest code.
// This would mean that updates to the golden file would have to be included
// in any change to the code generator, which would actually be fairly useful
// as it allows the reviewer to see clearly how the generated code is
// changing.
} // namespace
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@ -36,6 +36,7 @@
#include <string>
#include <google/protobuf/compiler/java/java_enum.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.pb.h>
@ -67,6 +68,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
EnumGenerator::~EnumGenerator() {}
void EnumGenerator::Generate(io::Printer* printer) {
WriteEnumDocComment(printer, descriptor_);
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public enum $classname$\n"
@ -85,6 +87,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
vars["name"] = canonical_values_[i]->name();
vars["index"] = SimpleItoa(canonical_values_[i]->index());
vars["number"] = SimpleItoa(canonical_values_[i]->number());
WriteEnumValueDocComment(printer, canonical_values_[i]);
printer->Print(vars,
"$name$($index$, $number$),\n");
}
@ -100,6 +103,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
vars["classname"] = descriptor_->name();
vars["name"] = aliases_[i].value->name();
vars["canonical_name"] = aliases_[i].canonical_value->name();
WriteEnumValueDocComment(printer, aliases_[i].value);
printer->Print(vars,
"public static final $classname$ $name$ = $canonical_name$;\n");
}
@ -108,6 +112,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
map<string, string> vars;
vars["name"] = descriptor_->value(i)->name();
vars["number"] = SimpleItoa(descriptor_->value(i)->number());
WriteEnumValueDocComment(printer, descriptor_->value(i));
printer->Print(vars,
"public static final int $name$_VALUE = $number$;\n");
}
@ -187,18 +192,29 @@ void EnumGenerator::Generate(io::Printer* printer) {
printer->Print(
"}\n"
"\n"
"private static final $classname$[] VALUES = {\n"
" ",
"private static final $classname$[] VALUES = ",
"classname", descriptor_->name());
if (CanUseEnumValues()) {
// If the constants we are going to output are exactly the ones we
// have declared in the Java enum in the same order, then we can use
// the values() method that the Java compiler automatically generates
// for every enum.
printer->Print("values();\n");
} else {
printer->Print(
"{\n"
" ");
for (int i = 0; i < descriptor_->value_count(); i++) {
printer->Print("$name$, ",
"name", descriptor_->value(i)->name());
}
printer->Print(
"\n"
"};\n"
"};\n");
}
printer->Print(
"\n"
"public static $classname$ valueOf(\n"
" com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n"
@ -237,6 +253,18 @@ void EnumGenerator::Generate(io::Printer* printer) {
printer->Print("}\n\n");
}
bool EnumGenerator::CanUseEnumValues() {
if (canonical_values_.size() != descriptor_->value_count()) {
return false;
}
for (int i = 0; i < descriptor_->value_count(); i++) {
if (descriptor_->value(i)->name() != canonical_values_[i]->name()) {
return false;
}
}
return true;
}
} // namespace java
} // namespace compiler
} // namespace protobuf

View File

@ -73,6 +73,8 @@ class EnumGenerator {
};
vector<Alias> aliases_;
bool CanUseEnumValues();
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
};

View File

@ -36,6 +36,7 @@
#include <string>
#include <google/protobuf/compiler/java/java_enum_field.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
@ -75,6 +76,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
// For singular messages and builders, one bit is used for the hasField bit.
(*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
(*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex);
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
(*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
@ -86,6 +88,13 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
// For repeated fields, one bit is used for whether the array is immutable
// in the parsing constructor.
(*variables)["get_mutable_bit_parser"] =
GenerateGetBitMutableLocal(builderBitIndex);
(*variables)["set_mutable_bit_parser"] =
GenerateSetBitMutableLocal(builderBitIndex);
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
@ -117,18 +126,25 @@ int EnumFieldGenerator::GetNumBitsForBuilder() const {
void EnumFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$boolean has$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$boolean has$capitalized_name$();\n"
"$deprecation$$type$ get$capitalized_name$();\n");
}
void EnumFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private $type$ $name$_;\n"
"private $type$ $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_message$;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" return $name$_;\n"
"}\n");
@ -137,13 +153,19 @@ GenerateMembers(io::Printer* printer) const {
void EnumFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
"private $type$ $name$_ = $default$;\n"
"private $type$ $name$_ = $default$;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_builder$;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" return $name$_;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
" if (value == null) {\n"
" throw new NullPointerException();\n"
@ -152,7 +174,9 @@ GenerateBuilderMembers(io::Printer* printer) const {
" $name$_ = value;\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder clear$capitalized_name$() {\n"
" $clear_has_field_bit_builder$;\n"
" $name$_ = $default$;\n"
@ -210,11 +234,16 @@ GenerateParsingCode(io::Printer* printer) const {
"if (value != null) {\n");
}
printer->Print(variables_,
" $set_has_field_bit_builder$;\n"
" $set_has_field_bit_message$;\n"
" $name$_ = value;\n"
"}\n");
}
void EnumFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
// noop for enums
}
void EnumFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
@ -273,22 +302,33 @@ int RepeatedEnumFieldGenerator::GetNumBitsForBuilder() const {
void RepeatedEnumFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$int get$capitalized_name$Count();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"
"$deprecation$int get$capitalized_name$Count();\n"
"$deprecation$$type$ get$capitalized_name$(int index);\n");
}
void RepeatedEnumFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private java.util.List<$type$> $name$_;\n"
"private java.util.List<$type$> $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Count() {\n"
" return $name$_.size();\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
@ -320,21 +360,29 @@ GenerateBuilderMembers(io::Printer* printer) const {
" $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
" $set_mutable_bit_builder$;\n"
" }\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
// Note: We return an unmodifiable list because otherwise the caller
// could hold on to the returned list and modify it after the message
// has been built, thus mutating the message which is supposed to be
// immutable.
"$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
" return java.util.Collections.unmodifiableList($name$_);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Count() {\n"
" return $name$_.size();\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$(\n"
" int index, $type$ value) {\n"
" if (value == null) {\n"
@ -344,7 +392,9 @@ GenerateBuilderMembers(io::Printer* printer) const {
" $name$_.set(index, value);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
" if (value == null) {\n"
" throw new NullPointerException();\n"
@ -353,14 +403,18 @@ GenerateBuilderMembers(io::Printer* printer) const {
" $name$_.add(value);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<? extends $type$> values) {\n"
" ensure$capitalized_name$IsMutable();\n"
" super.addAll(values, $name$_);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder clear$capitalized_name$() {\n"
" $name$_ = java.util.Collections.emptyList();\n"
" $clear_mutable_bit_builder$;\n"
@ -434,7 +488,11 @@ GenerateParsingCode(io::Printer* printer) const {
"if (value != null) {\n");
}
printer->Print(variables_,
" add$capitalized_name$(value);\n"
" if (!$get_mutable_bit_parser$) {\n"
" $name$_ = new java.util.ArrayList<$type$>();\n"
" $set_mutable_bit_parser$;\n"
" }\n"
" $name$_.add(value);\n"
"}\n");
}
@ -456,6 +514,14 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
"input.popLimit(oldLimit);\n");
}
void RepeatedEnumFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($get_mutable_bit_parser$) {\n"
" $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
"}\n");
}
void RepeatedEnumFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
if (descriptor_->options().packed()) {

View File

@ -61,6 +61,7 @@ class EnumFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
@ -96,6 +97,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator {
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;

View File

@ -33,6 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_extension.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
@ -130,6 +131,7 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
printer->Print(vars,
"public static final int $constant_name$ = $number$;\n");
WriteFieldDocComment(printer, descriptor_);
if (HasDescriptorMethods(descriptor_->file())) {
// Non-lite extensions
if (descriptor_->extension_scope() == NULL) {

View File

@ -66,6 +66,7 @@ class FieldGenerator {
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 GenerateParsingDoneCode(io::Printer* printer) const = 0;
virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer)

View File

@ -42,6 +42,7 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@ -51,18 +52,24 @@ namespace java {
namespace {
// Recursively searches the given message to see if it contains any extensions.
bool UsesExtensions(const Message& message) {
// Recursively searches the given message to collect extensions.
// Returns true if all the extensions can be recognized. The extensions will be
// appended in to the extensions parameter.
// Returns false when there are unknown fields, in which case the data in the
// extensions output parameter is not reliable and should be discarded.
bool CollectExtensions(const Message& message,
vector<const FieldDescriptor*>* extensions) {
const Reflection* reflection = message.GetReflection();
// We conservatively assume that unknown fields are extensions.
if (reflection->GetUnknownFields(message).field_count() > 0) return true;
// There are unknown fields that could be extensions, thus this call fails.
if (reflection->GetUnknownFields(message).field_count() > 0) return false;
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]->is_extension()) extensions->push_back(fields[i]);
if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
if (fields[i]->is_repeated()) {
@ -70,16 +77,56 @@ bool UsesExtensions(const Message& message) {
for (int j = 0; j < size; j++) {
const Message& sub_message =
reflection->GetRepeatedMessage(message, fields[i], j);
if (UsesExtensions(sub_message)) return true;
if (!CollectExtensions(sub_message, extensions)) return false;
}
} else {
const Message& sub_message = reflection->GetMessage(message, fields[i]);
if (UsesExtensions(sub_message)) return true;
if (!CollectExtensions(sub_message, extensions)) return false;
}
}
}
return false;
return true;
}
// Finds all extensions in the given message and its sub-messages. If the
// message contains unknown fields (which could be extensions), then those
// extensions are defined in alternate_pool.
// The message will be converted to a DynamicMessage backed by alternate_pool
// in order to handle this case.
void CollectExtensions(const FileDescriptorProto& file_proto,
const DescriptorPool& alternate_pool,
vector<const FieldDescriptor*>* extensions,
const string& file_data) {
if (!CollectExtensions(file_proto, extensions)) {
// There are unknown fields in the file_proto, which are probably
// extensions. We need to parse the data into a dynamic message based on the
// builder-pool to find out all extensions.
const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
file_proto.GetDescriptor()->full_name());
GOOGLE_CHECK(file_proto_desc)
<< "Find unknown fields in FileDescriptorProto when building "
<< file_proto.name()
<< ". It's likely that those fields are custom options, however, "
"descriptor.proto is not in the transitive dependencies. "
"This normally should not happen. Please report a bug.";
DynamicMessageFactory factory;
scoped_ptr<Message> dynamic_file_proto(
factory.GetPrototype(file_proto_desc)->New());
GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
// Collect the extensions again from the dynamic message. There should be no
// more unknown fields this time, i.e. all the custom options should be
// parsed as extensions now.
extensions->clear();
GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions))
<< "Find unknown fields in FileDescriptorProto when building "
<< file_proto.name()
<< ". It's likely that those fields are custom options, however, "
"those options cannot be recognized in the builder pool. "
"This normally should not happen. Please report a bug.";
}
}
@ -306,19 +353,32 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
.GenerateNonNestedInitializationCode(printer);
}
if (UsesExtensions(file_proto)) {
// Must construct an ExtensionRegistry containing all possible extensions
// Proto compiler builds a DescriptorPool, which holds all the descriptors to
// generate, when processing the ".proto" files. We call this DescriptorPool
// the parsed pool (a.k.a. file_->pool()).
//
// Note that when users try to extend the (.*)DescriptorProto in their
// ".proto" files, it does not affect the pre-built FileDescriptorProto class
// in proto compiler. When we put the descriptor data in the file_proto, those
// extensions become unknown fields.
//
// Now we need to find out all the extension value to the (.*)DescriptorProto
// in the file_proto message, and prepare an ExtensionRegistry to return.
//
// To find those extensions, we need to parse the data into a dynamic message
// of the FileDescriptor based on the builder-pool, then we can use
// reflections to find all extension fields
vector<const FieldDescriptor*> extensions;
CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
if (extensions.size() > 0) {
// Must construct an ExtensionRegistry containing all existing extensions
// and return it.
printer->Print(
"com.google.protobuf.ExtensionRegistry registry =\n"
" com.google.protobuf.ExtensionRegistry.newInstance();\n"
"registerAllExtensions(registry);\n");
for (int i = 0; i < file_->dependency_count(); i++) {
if (ShouldIncludeDependency(file_->dependency(i))) {
printer->Print(
"$dependency$.registerAllExtensions(registry);\n",
"dependency", ClassName(file_->dependency(i)));
}
" com.google.protobuf.ExtensionRegistry.newInstance();\n");
for (int i = 0; i < extensions.size(); i++) {
ExtensionGenerator(extensions[i]).GenerateRegistrationCode(printer);
}
printer->Print(
"return registry;\n");
@ -375,7 +435,9 @@ static void GenerateSibling(const string& package_dir,
printer.Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"\n");
"// source: $filename$\n"
"\n",
"filename", descriptor->file()->name());
if (!java_package.empty()) {
printer.Print(
"package $package$;\n"

View File

@ -177,6 +177,18 @@ string ToJavaName(const string& full_name, const FileDescriptor* file) {
return result;
}
string ClassName(const Descriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const EnumDescriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const ServiceDescriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const FileDescriptor* descriptor) {
string result = FileJavaPackage(descriptor);
if (!result.empty()) result += '.';
@ -427,8 +439,10 @@ string GetBitFieldNameForBit(int bitIndex) {
return GetBitFieldName(bitIndex / 32);
}
string GenerateGetBit(int bitIndex) {
string varName = GetBitFieldNameForBit(bitIndex);
namespace {
string GenerateGetBitInternal(const string& prefix, int bitIndex) {
string varName = prefix + GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
string mask = bit_masks[bitInVarIndex];
@ -436,8 +450,8 @@ string GenerateGetBit(int bitIndex) {
return result;
}
string GenerateSetBit(int bitIndex) {
string varName = GetBitFieldNameForBit(bitIndex);
string GenerateSetBitInternal(const string& prefix, int bitIndex) {
string varName = prefix + GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
string mask = bit_masks[bitInVarIndex];
@ -445,6 +459,16 @@ string GenerateSetBit(int bitIndex) {
return result;
}
} // namespace
string GenerateGetBit(int bitIndex) {
return GenerateGetBitInternal("", bitIndex);
}
string GenerateSetBit(int bitIndex) {
return GenerateSetBitInternal("", bitIndex);
}
string GenerateClearBit(int bitIndex) {
string varName = GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
@ -455,21 +479,19 @@ string GenerateClearBit(int bitIndex) {
}
string GenerateGetBitFromLocal(int bitIndex) {
string varName = "from_" + GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
string mask = bit_masks[bitInVarIndex];
string result = "((" + varName + " & " + mask + ") == " + mask + ")";
return result;
return GenerateGetBitInternal("from_", bitIndex);
}
string GenerateSetBitToLocal(int bitIndex) {
string varName = "to_" + GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
return GenerateSetBitInternal("to_", bitIndex);
}
string mask = bit_masks[bitInVarIndex];
string result = varName + " |= " + mask;
return result;
string GenerateGetBitMutableLocal(int bitIndex) {
return GenerateGetBitInternal("mutable_", bitIndex);
}
string GenerateSetBitMutableLocal(int bitIndex) {
return GenerateSetBitInternal("mutable_", bitIndex);
}
} // namespace java

View File

@ -78,19 +78,14 @@ string ToJavaName(const string& full_name, const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
// descriptor.
inline string ClassName(const Descriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
inline string ClassName(const EnumDescriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
inline string ClassName(const ServiceDescriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const Descriptor* descriptor);
string ClassName(const EnumDescriptor* descriptor);
string ClassName(const ServiceDescriptor* descriptor);
string ClassName(const FileDescriptor* descriptor);
inline string ExtensionIdentifierName(const FieldDescriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const FileDescriptor* descriptor);
// Get the unqualified name that should be used for a field's field
// number constant.
@ -205,6 +200,18 @@ string GenerateGetBitFromLocal(int bitIndex);
// Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
string GenerateSetBitToLocal(int bitIndex);
// Does the same as GenerateGetBit but operates on the bit field on a local
// variable. This is used by the parsing constructor to record if a repeated
// field is mutable.
// Example: "((mutable_bitField1_ & 0x04) == 0x04)"
string GenerateGetBitMutableLocal(int bitIndex);
// Does the same as GenerateSetBit but operates on the bit field on a local
// variable. This is used by the parsing constructor to record if a repeated
// field is mutable.
// Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
string GenerateSetBitMutableLocal(int bitIndex);
} // namespace java
} // namespace compiler
} // namespace protobuf

View File

@ -32,17 +32,23 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_message.h>
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/compiler/java/java_message.h>
#include <map>
#include <vector>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_enum.h>
#include <google/protobuf/compiler/java/java_extension.h>
#include <google/protobuf/compiler/java/java_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/io/printer.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
namespace google {
namespace protobuf {
@ -233,10 +239,8 @@ void MessageGenerator::GenerateStaticVariableInitializers(
"field_name",
UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
}
printer->Print("},\n"
" $classname$.class,\n"
" $classname$.Builder.class);\n",
"classname", ClassName(descriptor_));
printer->Print(
"});\n");
}
// Generate static member initializers for all nested types.
@ -250,7 +254,6 @@ void MessageGenerator::GenerateStaticVariableInitializers(
// ===================================================================
void MessageGenerator::GenerateInterface(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
@ -298,6 +301,10 @@ void MessageGenerator::Generate(io::Printer* printer) {
descriptor_->containing_type() == NULL &&
descriptor_->file()->options().java_multiple_files();
WriteMessageDocComment(printer, descriptor_);
// The builder_type stores the super type name of the nested Builder class.
string builder_type;
if (descriptor_->extension_range_count() > 0) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
@ -306,6 +313,9 @@ void MessageGenerator::Generate(io::Printer* printer) {
" $classname$> implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
builder_type = strings::Substitute(
"com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>",
ClassName(descriptor_));
} else {
printer->Print(
"public $static$ final class $classname$ extends\n"
@ -313,6 +323,9 @@ void MessageGenerator::Generate(io::Printer* printer) {
" $classname$> implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
builder_type = strings::Substitute(
"com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
ClassName(descriptor_));
}
} else {
if (HasDescriptorMethods(descriptor_)) {
@ -322,6 +335,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
" implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
} else {
printer->Print(
"public $static$ final class $classname$ extends\n"
@ -329,17 +343,28 @@ void MessageGenerator::Generate(io::Printer* printer) {
" implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
}
}
printer->Indent();
// Using builder_type, instead of Builder, prevents the Builder class from
// being loaded into PermGen space when the default instance is created.
// This optimizes the PermGen space usage for clients that do not modify
// messages.
printer->Print(
"// Use $classname$.newBuilder() to construct.\n"
"private $classname$(Builder builder) {\n"
"private $classname$($buildertype$ builder) {\n"
" super(builder);\n"
"}\n"
"$set_unknown_fields$\n"
"}\n",
"classname", descriptor_->name(),
"buildertype", builder_type,
"set_unknown_fields", HasUnknownFields(descriptor_)
? " this.unknownFields = builder.getUnknownFields();" : "");
printer->Print(
// 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"
"private $classname$(boolean noInit) {$set_default_unknown_fields$}\n"
"\n"
"private static final $classname$ defaultInstance;\n"
"public static $classname$ getDefaultInstance() {\n"
@ -350,9 +375,28 @@ void MessageGenerator::Generate(io::Printer* printer) {
" return defaultInstance;\n"
"}\n"
"\n",
"classname", descriptor_->name());
"classname", descriptor_->name(),
"set_default_unknown_fields", HasUnknownFields(descriptor_)
? " this.unknownFields ="
" com.google.protobuf.UnknownFieldSet.getDefaultInstance(); " : "");
if (HasUnknownFields(descriptor_)) {
printer->Print(
"private final com.google.protobuf.UnknownFieldSet unknownFields;\n"
""
"@java.lang.Override\n"
"public final com.google.protobuf.UnknownFieldSet\n"
" getUnknownFields() {\n"
" return this.unknownFields;\n"
"}\n");
}
if (HasGeneratedMethods(descriptor_)) {
GenerateParsingConstructor(printer);
}
GenerateDescriptorMethods(printer);
GenerateParser(printer);
// Nested types
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
@ -567,68 +611,54 @@ GenerateParseFromMethods(io::Printer* printer) {
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" return newBuilder().mergeFrom(data).buildParsed();\n"
" return PARSER.parseFrom(data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" return newBuilder().mergeFrom(data, extensionRegistry)\n"
" .buildParsed();\n"
" return PARSER.parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(byte[] data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" return newBuilder().mergeFrom(data).buildParsed();\n"
" return PARSER.parseFrom(data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" byte[] data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" return newBuilder().mergeFrom(data, extensionRegistry)\n"
" .buildParsed();\n"
" return PARSER.parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
" return newBuilder().mergeFrom(input).buildParsed();\n"
" return PARSER.parseFrom(input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
" return newBuilder().mergeFrom(input, extensionRegistry)\n"
" .buildParsed();\n"
" return PARSER.parseFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
" Builder builder = newBuilder();\n"
" if (builder.mergeDelimitedFrom(input)) {\n"
" return builder.buildParsed();\n"
" } else {\n"
" return null;\n"
" }\n"
" return PARSER.parseDelimitedFrom(input);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
" Builder builder = newBuilder();\n"
" if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n"
" return builder.buildParsed();\n"
" } else {\n"
" return null;\n"
" }\n"
" return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input)\n"
" throws java.io.IOException {\n"
" return newBuilder().mergeFrom(input).buildParsed();\n"
" return PARSER.parseFrom(input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
" return newBuilder().mergeFrom(input, extensionRegistry)\n"
" .buildParsed();\n"
" return PARSER.parseFrom(input, extensionRegistry);\n"
"}\n"
"\n",
"classname", ClassName(descriptor_));
@ -669,6 +699,8 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
"}\n");
}
WriteMessageDocComment(printer, descriptor_);
if (descriptor_->extension_range_count() > 0) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
@ -739,17 +771,25 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) {
if (HasDescriptorMethods(descriptor_)) {
if (!descriptor_->options().no_standard_descriptor_accessor()) {
printer->Print(
"public static final com.google.protobuf.Descriptors.Descriptor\n"
" getDescriptor() {\n"
" return $fileclass$.internal_$identifier$_descriptor;\n"
"}\n"
"\n"
"\n",
"fileclass", ClassName(descriptor_->file()),
"identifier", UniqueFileScopeIdentifier(descriptor_));
}
printer->Print(
"protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
" internalGetFieldAccessorTable() {\n"
" return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
" return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
" .ensureFieldAccessorsInitialized(\n"
" $classname$.class, $classname$.Builder.class);\n"
"}\n"
"\n",
"classname", ClassName(descriptor_),
"fileclass", ClassName(descriptor_->file()),
"identifier", UniqueFileScopeIdentifier(descriptor_));
}
@ -768,7 +808,8 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"private Builder(BuilderParent parent) {\n"
"private Builder(\n"
" com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
" super(parent);\n"
" maybeForceBuilderInitialization();\n"
"}\n",
@ -830,10 +871,11 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
printer->Print(
"public com.google.protobuf.Descriptors.Descriptor\n"
" getDescriptorForType() {\n"
" return $classname$.getDescriptor();\n"
" return $fileclass$.internal_$identifier$_descriptor;\n"
"}\n"
"\n",
"classname", ClassName(descriptor_));
"fileclass", ClassName(descriptor_->file()),
"identifier", UniqueFileScopeIdentifier(descriptor_));
}
printer->Print(
"public $classname$ getDefaultInstanceForType() {\n"
@ -853,16 +895,6 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
" return result;\n"
"}\n"
"\n"
"private $classname$ buildParsed()\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
" $classname$ result = buildPartial();\n"
" if (!result.isInitialized()) {\n"
" throw newUninitializedMessageException(\n"
" result).asInvalidProtocolBufferException();\n"
" }\n"
" return result;\n"
"}\n"
"\n"
"public $classname$ buildPartial() {\n"
" $classname$ result = new $classname$(this);\n",
"classname", ClassName(descriptor_));
@ -969,108 +1001,25 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
// ===================================================================
void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
scoped_array<const FieldDescriptor*> sorted_fields(
SortFieldsByNumber(descriptor_));
printer->Print(
"public Builder mergeFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n");
printer->Indent();
if (HasUnknownFields(descriptor_)) {
printer->Print(
"com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
" com.google.protobuf.UnknownFieldSet.newBuilder(\n"
" this.getUnknownFields());\n");
}
printer->Print(
"while (true) {\n");
printer->Indent();
printer->Print(
"int tag = input.readTag();\n"
"switch (tag) {\n");
printer->Indent();
if (HasUnknownFields(descriptor_)) {
printer->Print(
"case 0:\n" // zero signals EOF / limit reached
" this.setUnknownFields(unknownFields.build());\n"
" $on_changed$\n"
" throws java.io.IOException {\n"
" $classname$ parsedMessage = null;\n"
" try {\n"
" parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
" } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
" parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
" throw e;\n"
" } finally {\n"
" if (parsedMessage != null) {\n"
" mergeFrom(parsedMessage);\n"
" }\n"
" }\n"
" return this;\n"
"default: {\n"
" if (!parseUnknownField(input, unknownFields,\n"
" extensionRegistry, tag)) {\n"
" this.setUnknownFields(unknownFields.build());\n"
" $on_changed$\n"
" return this;\n" // it's an endgroup tag
" }\n"
" break;\n"
"}\n",
"on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
} else {
printer->Print(
"case 0:\n" // zero signals EOF / limit reached
" $on_changed$\n"
" return this;\n"
"default: {\n"
" if (!parseUnknownField(input, extensionRegistry, tag)) {\n"
" $on_changed$\n"
" return this;\n" // it's an endgroup tag
" }\n"
" break;\n"
"}\n",
"on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
}
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
uint32 tag = WireFormatLite::MakeTag(field->number(),
WireFormat::WireTypeForFieldType(field->type()));
printer->Print(
"case $tag$: {\n",
"tag", SimpleItoa(tag));
printer->Indent();
field_generators_.get(field).GenerateParsingCode(printer);
printer->Outdent();
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();
printer->Outdent();
printer->Outdent();
printer->Print(
" }\n" // switch (tag)
" }\n" // while (true)
"}\n"
"\n");
"classname", ClassName(descriptor_));
}
// ===================================================================
@ -1231,11 +1180,20 @@ void MessageGenerator::GenerateEqualsAndHashCode(io::Printer* printer) {
"}\n"
"\n");
printer->Print(
"private int memoizedHashCode = 0;\n");
printer->Print(
"@java.lang.Override\n"
"public int hashCode() {\n");
printer->Indent();
printer->Print(
"if (memoizedHashCode != 0) {\n");
printer->Indent();
printer->Print(
"return memoizedHashCode;\n");
printer->Outdent();
printer->Print(
"}\n"
"int hash = 41;\n"
"hash = (19 * hash) + getDescriptorForType().hashCode();\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
@ -1260,6 +1218,7 @@ void MessageGenerator::GenerateEqualsAndHashCode(io::Printer* printer) {
}
printer->Print(
"hash = (29 * hash) + getUnknownFields().hashCode();\n"
"memoizedHashCode = hash;\n"
"return hash;\n");
printer->Outdent();
printer->Print(
@ -1281,6 +1240,195 @@ void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
}
}
// ===================================================================
void MessageGenerator::GenerateParsingConstructor(io::Printer* printer) {
scoped_array<const FieldDescriptor*> sorted_fields(
SortFieldsByNumber(descriptor_));
printer->Print(
"private $classname$(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n",
"classname", descriptor_->name());
printer->Indent();
// Initialize all fields to default.
printer->Print(
"initFields();\n");
// Use builder bits to track mutable repeated fields.
int totalBuilderBits = 0;
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldGenerator& field = field_generators_.get(descriptor_->field(i));
totalBuilderBits += field.GetNumBitsForBuilder();
}
int totalBuilderInts = (totalBuilderBits + 31) / 32;
for (int i = 0; i < totalBuilderInts; i++) {
printer->Print("int mutable_$bit_field_name$ = 0;\n",
"bit_field_name", GetBitFieldName(i));
}
if (HasUnknownFields(descriptor_)) {
printer->Print(
"com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
" com.google.protobuf.UnknownFieldSet.newBuilder();\n");
}
printer->Print(
"try {\n");
printer->Indent();
printer->Print(
"boolean done = false;\n"
"while (!done) {\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
" done = true;\n"
" break;\n"
"default: {\n"
" if (!parseUnknownField(input,$unknown_fields$\n"
" extensionRegistry, tag)) {\n"
" done = true;\n" // it's an endgroup tag
" }\n"
" break;\n"
"}\n",
"unknown_fields", HasUnknownFields(descriptor_)
? " unknownFields," : "");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
uint32 tag = WireFormatLite::MakeTag(field->number(),
WireFormat::WireTypeForFieldType(field->type()));
printer->Print(
"case $tag$: {\n",
"tag", SimpleItoa(tag));
printer->Indent();
field_generators_.get(field).GenerateParsingCode(printer);
printer->Outdent();
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();
printer->Outdent();
printer->Print(
" }\n" // switch (tag)
"}\n"); // while (!done)
printer->Outdent();
printer->Print(
"} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
" throw e.setUnfinishedMessage(this);\n"
"} catch (java.io.IOException e) {\n"
" throw new com.google.protobuf.InvalidProtocolBufferException(\n"
" e.getMessage()).setUnfinishedMessage(this);\n"
"} finally {\n");
printer->Indent();
// Make repeated field list immutable.
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
field_generators_.get(field).GenerateParsingDoneCode(printer);
}
// Make unknown fields immutable.
if (HasUnknownFields(descriptor_)) {
printer->Print(
"this.unknownFields = unknownFields.build();\n");
}
// Make extensions immutable.
printer->Print(
"makeExtensionsImmutable();\n");
printer->Outdent();
printer->Outdent();
printer->Print(
" }\n" // finally
"}\n");
}
// ===================================================================
void MessageGenerator::GenerateParser(io::Printer* printer) {
printer->Print(
"public static com.google.protobuf.Parser<$classname$> PARSER =\n"
" new com.google.protobuf.AbstractParser<$classname$>() {\n",
"classname", descriptor_->name());
printer->Indent();
printer->Print(
"public $classname$ parsePartialFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n",
"classname", descriptor_->name());
if (HasGeneratedMethods(descriptor_)) {
printer->Print(
" return new $classname$(input, extensionRegistry);\n",
"classname", descriptor_->name());
} else {
// When parsing constructor isn't generated, use builder to parse messages.
// Note, will fallback to use reflection based mergeFieldFrom() in
// AbstractMessage.Builder.
printer->Indent();
printer->Print(
"Builder builder = newBuilder();\n"
"try {\n"
" builder.mergeFrom(input, extensionRegistry);\n"
"} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
" throw e.setUnfinishedMessage(builder.buildPartial());\n"
"} catch (java.io.IOException e) {\n"
" throw new com.google.protobuf.InvalidProtocolBufferException(\n"
" e.getMessage()).setUnfinishedMessage(builder.buildPartial());\n"
"}\n"
"return builder.buildPartial();\n");
printer->Outdent();
}
printer->Print(
"}\n");
printer->Outdent();
printer->Print(
"};\n"
"\n");
printer->Print(
"@java.lang.Override\n"
"public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
" return PARSER;\n"
"}\n"
"\n",
"classname", descriptor_->name());
}
} // namespace java
} // namespace compiler
} // namespace protobuf

View File

@ -95,6 +95,9 @@ class MessageGenerator {
UseMemoization useMemoization);
void GenerateEqualsAndHashCode(io::Printer* printer);
void GenerateParser(io::Printer* printer);
void GenerateParsingConstructor(io::Printer* printer);
const Descriptor* descriptor_;
FieldGeneratorMap field_generators_;

View File

@ -36,6 +36,7 @@
#include <string>
#include <google/protobuf/compiler/java/java_message_field.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
@ -73,6 +74,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// For singular messages and builders, one bit is used for the hasField bit.
(*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
(*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex);
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
(*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
@ -84,6 +86,13 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
// For repeated fields, one bit is used for whether the array is immutable
// in the parsing constructor.
(*variables)["get_mutable_bit_parser"] =
GenerateGetBitMutableLocal(builderBitIndex);
(*variables)["set_mutable_bit_parser"] =
GenerateSetBitMutableLocal(builderBitIndex);
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
@ -120,11 +129,15 @@ GenerateInterfaceMembers(io::Printer* printer) const {
// interface so that builders can choose dynamically to either return a
// message or a nested builder, so that asking for the interface doesn't
// cause a message to ever be built.
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$boolean has$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$boolean has$capitalized_name$();\n"
"$deprecation$$type$ get$capitalized_name$();\n");
if (HasNestedBuilders(descriptor_->containing_type())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
}
@ -133,15 +146,20 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private $type$ $name$_;\n"
"private $type$ $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_message$;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" return $name$_;\n"
"}\n");
if (HasNestedBuilders(descriptor_->containing_type())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
" return $name$_;\n"
@ -208,12 +226,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
// field of type "Field" called "Field".
// boolean hasField()
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_builder$;\n"
"}\n");
// Field getField()
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public $type$ get$capitalized_name$()",
@ -224,6 +244,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
NULL);
// Field.Builder setField(Field value)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder set$capitalized_name$($type$ value)",
@ -239,6 +260,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Field.Builder setField(Field.Builder builderForValue)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder set$capitalized_name$(\n"
" $type$.Builder builderForValue)",
@ -252,6 +274,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Field.Builder mergeField(Field value)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder merge$capitalized_name$($type$ value)",
@ -270,6 +293,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Field.Builder clearField()
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder clear$capitalized_name$()",
@ -282,19 +306,24 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
if (HasNestedBuilders(descriptor_->containing_type())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
" $set_has_field_bit_builder$;\n"
" $on_changed$\n"
" return get$capitalized_name$FieldBuilder().getBuilder();\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
" if ($name$Builder_ != null) {\n"
" return $name$Builder_.getMessageOrBuilder();\n"
" } else {\n"
" return $name$_;\n"
" }\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"private com.google.protobuf.SingleFieldBuilder<\n"
" $type$, $type$.Builder, $type$OrBuilder> \n"
" get$capitalized_name$FieldBuilder() {\n"
@ -357,21 +386,32 @@ GenerateBuildingCode(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"$type$.Builder subBuilder = $type$.newBuilder();\n"
"if (has$capitalized_name$()) {\n"
" subBuilder.mergeFrom(get$capitalized_name$());\n"
"$type$.Builder subBuilder = null;\n"
"if ($get_has_field_bit_message$) {\n"
" subBuilder = $name$_.toBuilder();\n"
"}\n");
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
"input.readGroup($number$, subBuilder, extensionRegistry);\n");
"$name$_ = input.readGroup($number$, $type$.PARSER,\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
"input.readMessage(subBuilder, extensionRegistry);\n");
"$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
}
printer->Print(variables_,
"set$capitalized_name$(subBuilder.buildPartial());\n");
"if (subBuilder != null) {\n"
" subBuilder.mergeFrom($name$_);\n"
" $name$_ = subBuilder.buildPartial();\n"
"}\n");
printer->Print(variables_,
"$set_has_field_bit_message$;\n");
}
void MessageFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
// noop for messages.
}
void MessageFieldGenerator::
@ -437,15 +477,23 @@ GenerateInterfaceMembers(io::Printer* printer) const {
// interface so that builders can choose dynamically to either return a
// message or a nested builder, so that asking for the interface doesn't
// cause a message to ever be built.
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.util.List<$type$> \n"
" get$capitalized_name$List();\n"
"$deprecation$$type$ get$capitalized_name$(int index);\n"
" get$capitalized_name$List();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$$type$ get$capitalized_name$(int index);\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$int get$capitalized_name$Count();\n");
if (HasNestedBuilders(descriptor_->containing_type())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.util.List<? extends $type$OrBuilder> \n"
" get$capitalized_name$OrBuilderList();\n"
" get$capitalized_name$OrBuilderList();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
" int index);\n");
}
@ -454,20 +502,30 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private java.util.List<$type$> $name$_;\n"
"private java.util.List<$type$> $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
" get$capitalized_name$OrBuilderList() {\n"
" return $name$_;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Count() {\n"
" return $name$_.size();\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
" int index) {\n"
" return $name$_.get(index);\n"
@ -552,6 +610,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
// repeated field of type "Field" called "RepeatedField".
// List<Field> getRepeatedFieldList()
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
@ -561,6 +620,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
NULL);
// int getRepeatedFieldCount()
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public int get$capitalized_name$Count()",
@ -570,6 +630,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
NULL);
// Field getRepeatedField(int index)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public $type$ get$capitalized_name$(int index)",
@ -580,6 +641,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
NULL);
// Builder setRepeatedField(int index, Field value)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder set$capitalized_name$(\n"
" int index, $type$ value)",
@ -593,6 +655,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder setRepeatedField(int index, Field.Builder builderForValue)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder set$capitalized_name$(\n"
" int index, $type$.Builder builderForValue)",
@ -606,6 +669,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder addRepeatedField(Field value)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder add$capitalized_name$($type$ value)",
@ -622,6 +686,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder addRepeatedField(int index, Field value)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder add$capitalized_name$(\n"
" int index, $type$ value)",
@ -638,6 +703,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder addRepeatedField(Field.Builder builderForValue)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder add$capitalized_name$(\n"
" $type$.Builder builderForValue)",
@ -651,6 +717,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder addRepeatedField(int index, Field.Builder builderForValue)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder add$capitalized_name$(\n"
" int index, $type$.Builder builderForValue)",
@ -664,6 +731,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder addAllRepeatedField(Iterable<Field> values)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<? extends $type$> values)",
@ -677,6 +745,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder clearAllRepeatedField()
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder clear$capitalized_name$()",
@ -689,6 +758,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
// Builder removeRepeatedField(int index)
WriteFieldDocComment(printer, descriptor_);
PrintNestedBuilderFunction(printer,
"$deprecation$public Builder remove$capitalized_name$(int index)",
@ -701,12 +771,15 @@ GenerateBuilderMembers(io::Printer* printer) const {
"return this;\n");
if (HasNestedBuilders(descriptor_->containing_type())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
" int index) {\n"
" return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
" int index) {\n"
" if ($name$Builder_ == null) {\n"
@ -714,8 +787,10 @@ GenerateBuilderMembers(io::Printer* printer) const {
" } else {\n"
" return $name$Builder_.getMessageOrBuilder(index);\n"
" }\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
" get$capitalized_name$OrBuilderList() {\n"
" if ($name$Builder_ != null) {\n"
@ -723,17 +798,23 @@ GenerateBuilderMembers(io::Printer* printer) const {
" } else {\n"
" return java.util.Collections.unmodifiableList($name$_);\n"
" }\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
" return get$capitalized_name$FieldBuilder().addBuilder(\n"
" $type$.getDefaultInstance());\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
" int index) {\n"
" return get$capitalized_name$FieldBuilder().addBuilder(\n"
" index, $type$.getDefaultInstance());\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<$type$.Builder> \n"
" get$capitalized_name$BuilderList() {\n"
" return get$capitalized_name$FieldBuilder().getBuilderList();\n"
@ -827,18 +908,27 @@ GenerateBuildingCode(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"$type$.Builder subBuilder = $type$.newBuilder();\n");
"if (!$get_mutable_bit_parser$) {\n"
" $name$_ = new java.util.ArrayList<$type$>();\n"
" $set_mutable_bit_parser$;\n"
"}\n");
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
"input.readGroup($number$, subBuilder, extensionRegistry);\n");
"$name$_.add(input.readGroup($number$, $type$.PARSER,\n"
" extensionRegistry));\n");
} else {
printer->Print(variables_,
"input.readMessage(subBuilder, extensionRegistry);\n");
"$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n");
}
}
void RepeatedMessageFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
printer->Print(variables_,
"add$capitalized_name$(subBuilder.buildPartial());\n");
"if ($get_mutable_bit_parser$) {\n"
" $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
"}\n");
}
void RepeatedMessageFieldGenerator::

View File

@ -61,6 +61,7 @@ class MessageFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
@ -102,6 +103,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;

View File

@ -36,6 +36,7 @@
#include <string>
#include <google/protobuf/compiler/java/java_primitive_field.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
@ -168,7 +169,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["field_type"] = (*variables)["type"];
(*variables)["field_list_type"] = "java.util.List<" +
(*variables)["boxed_type"] + ">";
(*variables)["empty_list"] = "java.util.Collections.emptyList();";
(*variables)["empty_list"] = "java.util.Collections.emptyList()";
(*variables)["default"] = DefaultValue(descriptor);
(*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
"" : ("= " + DefaultValue(descriptor));
@ -197,6 +198,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
// For singular messages and builders, one bit is used for the hasField bit.
(*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
(*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex);
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
(*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
@ -208,6 +210,13 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
// For repeated fields, one bit is used for whether the array is immutable
// in the parsing constructor.
(*variables)["get_mutable_bit_parser"] =
GenerateGetBitMutableLocal(builderBitIndex);
(*variables)["set_mutable_bit_parser"] =
GenerateSetBitMutableLocal(builderBitIndex);
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
@ -240,19 +249,26 @@ int PrimitiveFieldGenerator::GetNumBitsForBuilder() const {
void PrimitiveFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$boolean has$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$boolean has$capitalized_name$();\n"
"$deprecation$$type$ get$capitalized_name$();\n");
}
void PrimitiveFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private $field_type$ $name$_;\n"
"private $field_type$ $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_message$;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" return $name$_;\n"
@ -262,16 +278,21 @@ GenerateMembers(io::Printer* printer) const {
void PrimitiveFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
"private $field_type$ $name$_ $default_init$;\n"
"private $field_type$ $name$_ $default_init$;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_builder$;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" return $name$_;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
"$null_check$"
@ -279,7 +300,10 @@ GenerateBuilderMembers(io::Printer* printer) const {
" $name$_ = value;\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder clear$capitalized_name$() {\n"
" $clear_has_field_bit_builder$;\n");
JavaType type = GetJavaType(descriptor_);
@ -335,10 +359,15 @@ GenerateBuildingCode(io::Printer* printer) const {
void PrimitiveFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"$set_has_field_bit_builder$;\n"
"$set_has_field_bit_message$;\n"
"$name$_ = input.read$capitalized_type$();\n");
}
void PrimitiveFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
// noop for primitives.
}
void PrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
@ -468,9 +497,14 @@ int RepeatedPrimitiveFieldGenerator::GetNumBitsForBuilder() const {
void RepeatedPrimitiveFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$int get$capitalized_name$Count();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n"
"$deprecation$int get$capitalized_name$Count();\n"
"$deprecation$$type$ get$capitalized_name$(int index);\n");
}
@ -478,14 +512,20 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private $field_list_type$ $name$_;\n"
"private $field_list_type$ $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<$boxed_type$>\n"
" get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Count() {\n"
" return $name$_.size();\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
@ -523,17 +563,24 @@ GenerateBuilderMembers(io::Printer* printer) const {
// could hold on to the returned list and modify it after the message
// has been built, thus mutating the message which is supposed to be
// immutable.
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<$boxed_type$>\n"
" get$capitalized_name$List() {\n"
" return java.util.Collections.unmodifiableList($name$_);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Count() {\n"
" return $name$_.size();\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$(\n"
" int index, $type$ value) {\n"
"$null_check$"
@ -541,21 +588,27 @@ GenerateBuilderMembers(io::Printer* printer) const {
" $name$_.set(index, value);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
"$null_check$"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.add(value);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<? extends $boxed_type$> values) {\n"
" ensure$capitalized_name$IsMutable();\n"
" super.addAll(values, $name$_);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder clear$capitalized_name$() {\n"
" $name$_ = $empty_list$;\n"
" $clear_mutable_bit_builder$;\n"
@ -616,7 +669,10 @@ GenerateBuildingCode(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"ensure$capitalized_name$IsMutable();\n"
"if (!$get_mutable_bit_parser$) {\n"
" $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
" $set_mutable_bit_parser$;\n"
"}\n"
"$name$_.add(input.read$capitalized_type$());\n");
}
@ -625,12 +681,24 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
printer->Print(variables_,
"int length = input.readRawVarint32();\n"
"int limit = input.pushLimit(length);\n"
"if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
" $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
" $set_mutable_bit_parser$;\n"
"}\n"
"while (input.getBytesUntilLimit() > 0) {\n"
" add$capitalized_name$(input.read$capitalized_type$());\n"
" $name$_.add(input.read$capitalized_type$());\n"
"}\n"
"input.popLimit(limit);\n");
}
void RepeatedPrimitiveFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($get_mutable_bit_parser$) {\n"
" $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
"}\n");
}
void RepeatedPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
if (descriptor_->options().packed()) {

View File

@ -61,6 +61,7 @@ class PrimitiveFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
@ -96,6 +97,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;

View File

@ -33,6 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/java/java_service.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.pb.h>
@ -50,6 +51,7 @@ ServiceGenerator::~ServiceGenerator() {}
void ServiceGenerator::Generate(io::Printer* printer) {
bool is_own_file = descriptor_->file()->options().java_multiple_files();
WriteServiceDocComment(printer, descriptor_);
printer->Print(
"public $static$ abstract class $classname$\n"
" implements com.google.protobuf.Service {\n",
@ -86,6 +88,12 @@ void ServiceGenerator::Generate(io::Printer* printer) {
GenerateStub(printer);
GenerateBlockingStub(printer);
// Add an insertion point.
printer->Print(
"\n"
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
"full_name", descriptor_->full_name());
printer->Outdent();
printer->Print("}\n\n");
}
@ -157,6 +165,7 @@ void ServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
void ServiceGenerator::GenerateAbstractMethods(io::Printer* printer) {
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor* method = descriptor_->method(i);
WriteMethodDocComment(printer, method);
GenerateMethodSignature(printer, method, IS_ABSTRACT);
printer->Print(";\n\n");
}

View File

@ -37,6 +37,7 @@
#include <string>
#include <google/protobuf/compiler/java/java_string_field.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
@ -85,6 +86,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
// For singular messages and builders, one bit is used for the hasField bit.
(*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
(*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex);
(*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
(*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
@ -96,6 +98,13 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
(*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
// For repeated fields, one bit is used for whether the array is immutable
// in the parsing constructor.
(*variables)["get_mutable_bit_parser"] =
GenerateGetBitMutableLocal(builderBitIndex);
(*variables)["set_mutable_bit_parser"] =
GenerateSetBitMutableLocal(builderBitIndex);
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(builderBitIndex);
(*variables)["set_has_field_bit_to_local"] =
@ -160,39 +169,53 @@ int StringFieldGenerator::GetNumBitsForBuilder() const {
// UnmodifiableLazyStringList.
void StringFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$boolean has$capitalized_name$();\n"
"$deprecation$String get$capitalized_name$();\n");
"$deprecation$boolean has$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.lang.String get$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes();\n");
}
void StringFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private java.lang.Object $name$_;\n"
"private java.lang.Object $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_message$;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public String get$capitalized_name$() {\n"
"$deprecation$public java.lang.String get$capitalized_name$() {\n"
" java.lang.Object ref = $name$_;\n"
" if (ref instanceof String) {\n"
" return (String) ref;\n"
" if (ref instanceof java.lang.String) {\n"
" return (java.lang.String) ref;\n"
" } else {\n"
" com.google.protobuf.ByteString bs = \n"
" (com.google.protobuf.ByteString) ref;\n"
" String s = bs.toStringUtf8();\n"
" if (com.google.protobuf.Internal.isValidUtf8(bs)) {\n"
" java.lang.String s = bs.toStringUtf8();\n"
" if (bs.isValidUtf8()) {\n"
" $name$_ = s;\n"
" }\n"
" return s;\n"
" }\n"
"}\n"
"private com.google.protobuf.ByteString get$capitalized_name$Bytes() {\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes() {\n"
" java.lang.Object ref = $name$_;\n"
" if (ref instanceof String) {\n"
" if (ref instanceof java.lang.String) {\n"
" com.google.protobuf.ByteString b = \n"
" com.google.protobuf.ByteString.copyFromUtf8((String) ref);\n"
" com.google.protobuf.ByteString.copyFromUtf8(\n"
" (java.lang.String) ref);\n"
" $name$_ = b;\n"
" return b;\n"
" } else {\n"
@ -204,31 +227,55 @@ GenerateMembers(io::Printer* printer) const {
void StringFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
"private java.lang.Object $name$_ $default_init$;\n"
"private java.lang.Object $name$_ $default_init$;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public boolean has$capitalized_name$() {\n"
" return $get_has_field_bit_builder$;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public String get$capitalized_name$() {\n"
"$deprecation$public java.lang.String get$capitalized_name$() {\n"
" java.lang.Object ref = $name$_;\n"
" if (!(ref instanceof String)) {\n"
" String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();\n"
" if (!(ref instanceof java.lang.String)) {\n"
" java.lang.String s = ((com.google.protobuf.ByteString) ref)\n"
" .toStringUtf8();\n"
" $name$_ = s;\n"
" return s;\n"
" } else {\n"
" return (String) ref;\n"
" return (java.lang.String) ref;\n"
" }\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$(String value) {\n"
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes() {\n"
" java.lang.Object ref = $name$_;\n"
" if (ref instanceof String) {\n"
" com.google.protobuf.ByteString b = \n"
" com.google.protobuf.ByteString.copyFromUtf8(\n"
" (java.lang.String) ref);\n"
" $name$_ = b;\n"
" return b;\n"
" } else {\n"
" return (com.google.protobuf.ByteString) ref;\n"
" }\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$(\n"
" java.lang.String value) {\n"
"$null_check$"
" $set_has_field_bit_builder$;\n"
" $name$_ = value;\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder clear$capitalized_name$() {\n"
" $clear_has_field_bit_builder$;\n");
// The default value is not a simple literal so we want to avoid executing
@ -240,11 +287,15 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"void set$capitalized_name$(com.google.protobuf.ByteString value) {\n"
"$deprecation$public Builder set$capitalized_name$Bytes(\n"
" com.google.protobuf.ByteString value) {\n"
"$null_check$"
" $set_has_field_bit_builder$;\n"
" $name$_ = value;\n"
" $on_changed$\n"
" return this;\n"
"}\n");
}
@ -267,9 +318,13 @@ GenerateBuilderClearCode(io::Printer* printer) const {
void StringFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
// Allow a slight breach of abstraction here in order to avoid forcing
// all string fields to Strings when copying fields from a Message.
printer->Print(variables_,
"if (other.has$capitalized_name$()) {\n"
" set$capitalized_name$(other.get$capitalized_name$());\n"
" $set_has_field_bit_builder$;\n"
" $name$_ = other.$name$_;\n"
" $on_changed$\n"
"}\n");
}
@ -285,10 +340,15 @@ GenerateBuildingCode(io::Printer* printer) const {
void StringFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"$set_has_field_bit_builder$;\n"
"$set_has_field_bit_message$;\n"
"$name$_ = input.readBytes();\n");
}
void StringFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
// noop for strings.
}
void StringFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
@ -322,7 +382,7 @@ GenerateHashCode(io::Printer* printer) const {
}
string StringFieldGenerator::GetBoxedType() const {
return "String";
return "java.lang.String";
}
@ -350,27 +410,49 @@ int RepeatedStringFieldGenerator::GetNumBitsForBuilder() const {
void RepeatedStringFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.util.List<String> get$capitalized_name$List();\n"
"$deprecation$int get$capitalized_name$Count();\n"
"$deprecation$String get$capitalized_name$(int index);\n");
"$deprecation$java.util.List<java.lang.String>\n"
"get$capitalized_name$List();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$int get$capitalized_name$Count();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$java.lang.String get$capitalized_name$(int index);\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes(int index);\n");
}
void RepeatedStringFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private com.google.protobuf.LazyStringList $name$_;\n"
"$deprecation$public java.util.List<String>\n"
"private com.google.protobuf.LazyStringList $name$_;\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<java.lang.String>\n"
" get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Count() {\n"
" return $name$_.size();\n"
"}\n"
"$deprecation$public String get$capitalized_name$(int index) {\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes(int index) {\n"
" return $name$_.getByteString(index);\n"
"}\n");
if (descriptor_->options().packed() &&
HasGeneratedMethods(descriptor_->containing_type())) {
@ -405,39 +487,59 @@ GenerateBuilderMembers(io::Printer* printer) const {
// could hold on to the returned list and modify it after the message
// has been built, thus mutating the message which is supposed to be
// immutable.
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.util.List<String>\n"
"$deprecation$public java.util.List<java.lang.String>\n"
" get$capitalized_name$List() {\n"
" return java.util.Collections.unmodifiableList($name$_);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Count() {\n"
" return $name$_.size();\n"
"}\n"
"$deprecation$public String get$capitalized_name$(int index) {\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes(int index) {\n"
" return $name$_.getByteString(index);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$(\n"
" int index, String value) {\n"
" int index, java.lang.String value) {\n"
"$null_check$"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.set(index, value);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"$deprecation$public Builder add$capitalized_name$(String value) {\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder add$capitalized_name$(\n"
" java.lang.String value) {\n"
"$null_check$"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.add(value);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<String> values) {\n"
" java.lang.Iterable<java.lang.String> values) {\n"
" ensure$capitalized_name$IsMutable();\n"
" super.addAll(values, $name$_);\n"
" $on_changed$\n"
" return this;\n"
"}\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public Builder clear$capitalized_name$() {\n"
" $name$_ = $empty_list$;\n"
" $clear_mutable_bit_builder$;\n"
@ -445,11 +547,15 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"void add$capitalized_name$(com.google.protobuf.ByteString value) {\n"
"$deprecation$public Builder add$capitalized_name$Bytes(\n"
" com.google.protobuf.ByteString value) {\n"
"$null_check$"
" ensure$capitalized_name$IsMutable();\n"
" $name$_.add(value);\n"
" $on_changed$\n"
" return this;\n"
"}\n");
}
@ -507,7 +613,10 @@ GenerateBuildingCode(io::Printer* printer) const {
void RepeatedStringFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"ensure$capitalized_name$IsMutable();\n"
"if (!$get_mutable_bit_parser$) {\n"
" $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
" $set_mutable_bit_parser$;\n"
"}\n"
"$name$_.add(input.readBytes());\n");
}
@ -516,12 +625,24 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
printer->Print(variables_,
"int length = input.readRawVarint32();\n"
"int limit = input.pushLimit(length);\n"
"if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
" $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
" $set_mutable_bit_parser$;\n"
"}\n"
"while (input.getBytesUntilLimit() > 0) {\n"
" add$capitalized_name$(input.read$capitalized_type$());\n"
" $name$.add(input.read$capitalized_type$());\n"
"}\n"
"input.popLimit(limit);\n");
}
void RepeatedStringFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($get_mutable_bit_parser$) {\n"
" $name$_ = new com.google.protobuf.UnmodifiableLazyStringList($name$_);\n"
"}\n");
}
void RepeatedStringFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
if (descriptor_->options().packed()) {

View File

@ -62,6 +62,7 @@ class StringFieldGenerator : public FieldGenerator {
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
@ -96,6 +97,7 @@ class RepeatedStringFieldGenerator : public FieldGenerator {
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;

View File

@ -43,7 +43,7 @@ int main(int argc, char* argv[]) {
// Proto2 C++
google::protobuf::compiler::cpp::CppGenerator cpp_generator;
cli.RegisterGenerator("--cpp_out", &cpp_generator,
cli.RegisterGenerator("--cpp_out", "--cpp_opt", &cpp_generator,
"Generate C++ header and source.");
// Proto2 Java

View File

@ -33,13 +33,14 @@
#include <google/protobuf/compiler/mock_code_generator.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/descriptor.pb.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>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@ -132,6 +133,15 @@ bool MockCodeGenerator::Generate(
} else if (command == "Abort") {
cerr << "Saw message type MockCodeGenerator_Abort." << endl;
abort();
} else if (command == "HasSourceCodeInfo") {
FileDescriptorProto file_descriptor_proto;
file->CopySourceCodeInfoTo(&file_descriptor_proto);
bool has_source_code_info =
file_descriptor_proto.has_source_code_info() &&
file_descriptor_proto.source_code_info().location_size() > 0;
cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: "
<< has_source_code_info << "." << endl;
abort();
} else {
GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
}

View File

@ -59,6 +59,10 @@ namespace compiler {
// MockCodeGenerator_Exit." to stderr and then calls exit(123).
// MockCodeGenerator_Abort: Generate() prints "Saw message type
// MockCodeGenerator_Abort." to stderr and then calls abort().
// MockCodeGenerator_HasSourceCodeInfo: Causes Generate() to abort after
// printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to
// stderr, where FOO is "1" if the supplied FileDescriptorProto has source
// code info, and "0" otherwise.
class MockCodeGenerator : public CodeGenerator {
public:
MockCodeGenerator(const string& name);

View File

@ -174,6 +174,20 @@ bool Parser::ConsumeInteger(int* output, const char* error) {
}
}
bool Parser::ConsumeSignedInteger(int* output, const char* error) {
bool is_negative = false;
uint64 max_value = kint32max;
if (TryConsume("-")) {
is_negative = true;
max_value += 1;
}
uint64 value = 0;
DO(ConsumeInteger64(max_value, &value, error));
if (is_negative) value *= -1;
*output = value;
return true;
}
bool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
const char* error) {
if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
@ -237,6 +251,35 @@ bool Parser::ConsumeString(string* output, const char* error) {
}
}
bool Parser::TryConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location) {
if (LookingAt(text)) {
string leading, trailing;
input_->NextWithComments(&trailing, NULL, &leading);
// Save the leading comments for next time, and recall the leading comments
// from last time.
leading.swap(upcoming_doc_comments_);
if (location != NULL) {
location->AttachComments(&leading, &trailing);
}
return true;
} else {
return false;
}
}
bool Parser::ConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location) {
if (TryConsumeEndOfDeclaration(text, location)) {
return true;
} else {
AddError("Expected \"" + string(text) + "\".");
return false;
}
}
// -------------------------------------------------------------------
void Parser::AddError(int line, int column, const string& error) {
@ -315,6 +358,19 @@ void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
}
}
void Parser::LocationRecorder::AttachComments(
string* leading, string* trailing) const {
GOOGLE_CHECK(!location_->has_leading_comments());
GOOGLE_CHECK(!location_->has_trailing_comments());
if (!leading->empty()) {
location_->mutable_leading_comments()->swap(*leading);
}
if (!trailing->empty()) {
location_->mutable_trailing_comments()->swap(*trailing);
}
}
// -------------------------------------------------------------------
void Parser::SkipStatement() {
@ -322,7 +378,7 @@ void Parser::SkipStatement() {
if (AtEnd()) {
return;
} else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
if (TryConsume(";")) {
if (TryConsumeEndOfDeclaration(";", NULL)) {
return;
} else if (TryConsume("{")) {
SkipRestOfBlock();
@ -340,7 +396,7 @@ void Parser::SkipRestOfBlock() {
if (AtEnd()) {
return;
} else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
if (TryConsume("}")) {
if (TryConsumeEndOfDeclaration("}", NULL)) {
return;
} else if (TryConsume("{")) {
SkipRestOfBlock();
@ -366,7 +422,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
if (LookingAtType(io::Tokenizer::TYPE_START)) {
// Advance to first token.
input_->Next();
input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
}
{
@ -393,7 +449,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
if (LookingAt("}")) {
AddError("Unmatched \"}\".");
input_->Next();
input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
}
}
}
@ -411,7 +467,7 @@ bool Parser::ParseSyntaxIdentifier() {
io::Tokenizer::Token syntax_token = input_->current();
string syntax;
DO(ConsumeString(&syntax, "Expected syntax identifier."));
DO(Consume(";"));
DO(ConsumeEndOfDeclaration(";", NULL));
syntax_identifier_ = syntax;
@ -427,7 +483,7 @@ bool Parser::ParseSyntaxIdentifier() {
bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
const LocationRecorder& root_location) {
if (TryConsume(";")) {
if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("message")) {
@ -451,14 +507,16 @@ bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
FileDescriptorProto::kMessageTypeFieldNumber,
location);
} else if (LookingAt("import")) {
int index = file->dependency_size();
return ParseImport(file->add_dependency(), root_location, index);
return ParseImport(file->mutable_dependency(),
file->mutable_public_dependency(),
file->mutable_weak_dependency(),
root_location);
} else if (LookingAt("package")) {
return ParsePackage(file, root_location);
} else if (LookingAt("option")) {
LocationRecorder location(root_location,
FileDescriptorProto::kOptionsFieldNumber);
return ParseOption(file->mutable_options(), location);
return ParseOption(file->mutable_options(), location, OPTION_STATEMENT);
} else {
AddError("Expected top-level statement (e.g. \"message\").");
return false;
@ -482,11 +540,45 @@ bool Parser::ParseMessageDefinition(DescriptorProto* message,
return true;
}
namespace {
const int kMaxExtensionRangeSentinel = -1;
bool IsMessageSetWireFormatMessage(const DescriptorProto& message) {
const MessageOptions& options = message.options();
for (int i = 0; i < options.uninterpreted_option_size(); ++i) {
const UninterpretedOption& uninterpreted = options.uninterpreted_option(i);
if (uninterpreted.name_size() == 1 &&
uninterpreted.name(0).name_part() == "message_set_wire_format" &&
uninterpreted.identifier_value() == "true") {
return true;
}
}
return false;
}
// Modifies any extension ranges that specified 'max' as the end of the
// extension range, and sets them to the type-specific maximum. The actual max
// tag number can only be determined after all options have been parsed.
void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) {
const bool is_message_set = IsMessageSetWireFormatMessage(*message);
const int max_extension_number = is_message_set ?
kint32max :
FieldDescriptor::kMaxNumber + 1;
for (int i = 0; i < message->extension_range_size(); ++i) {
if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) {
message->mutable_extension_range(i)->set_end(max_extension_number);
}
}
}
} // namespace
bool Parser::ParseMessageBlock(DescriptorProto* message,
const LocationRecorder& message_location) {
DO(Consume("{"));
DO(ConsumeEndOfDeclaration("{", &message_location));
while (!TryConsume("}")) {
while (!TryConsumeEndOfDeclaration("}", NULL)) {
if (AtEnd()) {
AddError("Reached end of input in message definition (missing '}').");
return false;
@ -499,12 +591,15 @@ bool Parser::ParseMessageBlock(DescriptorProto* message,
}
}
if (message->extension_range_size() > 0) {
AdjustExtensionRangesWithMaxEndNumber(message);
}
return true;
}
bool Parser::ParseMessageStatement(DescriptorProto* message,
const LocationRecorder& message_location) {
if (TryConsume(";")) {
if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("message")) {
@ -532,7 +627,7 @@ bool Parser::ParseMessageStatement(DescriptorProto* message,
} else if (LookingAt("option")) {
LocationRecorder location(message_location,
DescriptorProto::kOptionsFieldNumber);
return ParseOption(message->mutable_options(), location);
return ParseOption(message->mutable_options(), location, OPTION_STATEMENT);
} else {
LocationRecorder location(message_location,
DescriptorProto::kFieldFieldNumber,
@ -647,7 +742,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field,
return false;
}
} else {
DO(Consume(";"));
DO(ConsumeEndOfDeclaration(";", &field_location));
}
return true;
@ -669,7 +764,7 @@ bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
// the default value is not actually an option.
DO(ParseDefaultAssignment(field, field_location));
} else {
DO(ParseOptionAssignment(field->mutable_options(), location));
DO(ParseOption(field->mutable_options(), location, OPTION_ASSIGNMENT));
}
} while (TryConsume(","));
@ -835,6 +930,8 @@ bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
bool Parser::ParseUninterpretedBlock(string* value) {
// Note that enclosing braces are not added to *value.
// We do NOT use ConsumeEndOfStatement for this brace because it's delimiting
// an expression, not a block of statements.
DO(Consume("{"));
int brace_depth = 1;
while (!AtEnd()) {
@ -858,8 +955,9 @@ bool Parser::ParseUninterpretedBlock(string* value) {
// We don't interpret the option here. Instead we store it in an
// UninterpretedOption, to be interpreted later.
bool Parser::ParseOptionAssignment(Message* options,
const LocationRecorder& options_location) {
bool Parser::ParseOption(Message* options,
const LocationRecorder& options_location,
OptionStyle style) {
// Create an entry in the uninterpreted_option field.
const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
FindFieldByName("uninterpreted_option");
@ -872,6 +970,10 @@ bool Parser::ParseOptionAssignment(Message* options,
options_location, uninterpreted_option_field->number(),
reflection->FieldSize(*options, uninterpreted_option_field));
if (style == OPTION_STATEMENT) {
DO(Consume("option"));
}
UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
options->GetReflection()->AddMessage(options,
uninterpreted_option_field));
@ -899,6 +1001,7 @@ bool Parser::ParseOptionAssignment(Message* options,
DO(Consume("="));
{
LocationRecorder value_location(location);
value_location.RecordLegacyLocation(
uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
@ -917,7 +1020,8 @@ bool Parser::ParseOptionAssignment(Message* options,
return false;
case io::Tokenizer::TYPE_IDENTIFIER: {
value_location.AddPath(UninterpretedOption::kIdentifierValueFieldNumber);
value_location.AddPath(
UninterpretedOption::kIdentifierValueFieldNumber);
if (is_negative) {
AddError("Invalid '-' symbol before identifier.");
return false;
@ -936,7 +1040,8 @@ bool Parser::ParseOptionAssignment(Message* options,
if (is_negative) {
value_location.AddPath(
UninterpretedOption::kNegativeIntValueFieldNumber);
uninterpreted_option->set_negative_int_value(-static_cast<int64>(value));
uninterpreted_option->set_negative_int_value(
-static_cast<int64>(value));
} else {
value_location.AddPath(
UninterpretedOption::kPositiveIntValueFieldNumber);
@ -967,7 +1072,8 @@ bool Parser::ParseOptionAssignment(Message* options,
case io::Tokenizer::TYPE_SYMBOL:
if (LookingAt("{")) {
value_location.AddPath(UninterpretedOption::kAggregateValueFieldNumber);
value_location.AddPath(
UninterpretedOption::kAggregateValueFieldNumber);
DO(ParseUninterpretedBlock(
uninterpreted_option->mutable_aggregate_value()));
} else {
@ -976,6 +1082,11 @@ bool Parser::ParseOptionAssignment(Message* options,
}
break;
}
}
if (style == OPTION_STATEMENT) {
DO(ConsumeEndOfDeclaration(";", &location));
}
return true;
}
@ -1008,7 +1119,10 @@ bool Parser::ParseExtensions(DescriptorProto* message,
LocationRecorder end_location(
location, DescriptorProto::ExtensionRange::kEndFieldNumber);
if (TryConsume("max")) {
end = FieldDescriptor::kMaxNumber;
// Set to the sentinel value - 1 since we increment the value below.
// The actual value of the end of the range should be set with
// AdjustExtensionRangesWithMaxEndNumber.
end = kMaxExtensionRangeSentinel - 1;
} else {
DO(ConsumeInteger(&end, "Expected integer."));
}
@ -1028,7 +1142,7 @@ bool Parser::ParseExtensions(DescriptorProto* message,
range->set_end(end);
} while (TryConsume(","));
DO(Consume(";"));
DO(ConsumeEndOfDeclaration(";", &extensions_location));
return true;
}
@ -1046,7 +1160,7 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
io::Tokenizer::Token extendee_end = input_->previous();
// Parse the block.
DO(Consume("{"));
DO(ConsumeEndOfDeclaration("{", &extend_location));
bool is_first = true;
@ -1083,7 +1197,7 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
// other statements.
SkipStatement();
}
} while(!TryConsume("}"));
} while (!TryConsumeEndOfDeclaration("}", NULL));
return true;
}
@ -1109,9 +1223,9 @@ bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
const LocationRecorder& enum_location) {
DO(Consume("{"));
DO(ConsumeEndOfDeclaration("{", &enum_location));
while (!TryConsume("}")) {
while (!TryConsumeEndOfDeclaration("}", NULL)) {
if (AtEnd()) {
AddError("Reached end of input in enum definition (missing '}').");
return false;
@ -1129,13 +1243,14 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
const LocationRecorder& enum_location) {
if (TryConsume(";")) {
if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("option")) {
LocationRecorder location(enum_location,
EnumDescriptorProto::kOptionsFieldNumber);
return ParseOption(enum_type->mutable_options(), location);
return ParseOption(enum_type->mutable_options(), location,
OPTION_STATEMENT);
} else {
LocationRecorder location(enum_location,
EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
@ -1164,16 +1279,14 @@ bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
location.RecordLegacyLocation(
enum_value, DescriptorPool::ErrorCollector::NUMBER);
bool is_negative = TryConsume("-");
int number;
DO(ConsumeInteger(&number, "Expected integer."));
if (is_negative) number *= -1;
DO(ConsumeSignedInteger(&number, "Expected integer."));
enum_value->set_number(number);
}
DO(ParseEnumConstantOptions(enum_value, enum_value_location));
DO(Consume(";"));
DO(ConsumeEndOfDeclaration(";", &enum_value_location));
return true;
}
@ -1189,7 +1302,7 @@ bool Parser::ParseEnumConstantOptions(
DO(Consume("["));
do {
DO(ParseOptionAssignment(value->mutable_options(), location));
DO(ParseOption(value->mutable_options(), location, OPTION_ASSIGNMENT));
} while (TryConsume(","));
DO(Consume("]"));
@ -1217,9 +1330,9 @@ bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service,
bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
const LocationRecorder& service_location) {
DO(Consume("{"));
DO(ConsumeEndOfDeclaration("{", &service_location));
while (!TryConsume("}")) {
while (!TryConsumeEndOfDeclaration("}", NULL)) {
if (AtEnd()) {
AddError("Reached end of input in service definition (missing '}').");
return false;
@ -1237,13 +1350,13 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
const LocationRecorder& service_location) {
if (TryConsume(";")) {
if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
return true;
} else if (LookingAt("option")) {
LocationRecorder location(
service_location, ServiceDescriptorProto::kOptionsFieldNumber);
return ParseOption(service->mutable_options(), location);
return ParseOption(service->mutable_options(), location, OPTION_STATEMENT);
} else {
LocationRecorder location(service_location,
ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
@ -1286,29 +1399,42 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
}
DO(Consume(")"));
if (TryConsume("{")) {
if (LookingAt("{")) {
// Options!
while (!TryConsume("}")) {
DO(ParseOptions(method_location,
MethodDescriptorProto::kOptionsFieldNumber,
method->mutable_options()));
} else {
DO(ConsumeEndOfDeclaration(";", &method_location));
}
return true;
}
bool Parser::ParseOptions(const LocationRecorder& parent_location,
const int optionsFieldNumber,
Message* mutable_options) {
// Options!
ConsumeEndOfDeclaration("{", &parent_location);
while (!TryConsumeEndOfDeclaration("}", NULL)) {
if (AtEnd()) {
AddError("Reached end of input in method options (missing '}').");
return false;
}
if (TryConsume(";")) {
if (TryConsumeEndOfDeclaration(";", NULL)) {
// empty statement; ignore
} else {
LocationRecorder location(method_location,
MethodDescriptorProto::kOptionsFieldNumber);
if (!ParseOption(method->mutable_options(), location)) {
LocationRecorder location(parent_location,
optionsFieldNumber);
if (!ParseOption(mutable_options, location, OPTION_STATEMENT)) {
// This statement failed to parse. Skip it, but keep looping to
// parse other statements.
SkipStatement();
}
}
}
} else {
DO(Consume(";"));
}
return true;
}
@ -1406,32 +1532,44 @@ bool Parser::ParsePackage(FileDescriptorProto* file,
if (!TryConsume(".")) break;
file->mutable_package()->append(".");
}
location.EndAt(input_->previous());
DO(ConsumeEndOfDeclaration(";", &location));
}
DO(Consume(";"));
return true;
}
bool Parser::ParseImport(string* import_filename,
const LocationRecorder& root_location,
int index) {
bool Parser::ParseImport(RepeatedPtrField<string>* dependency,
RepeatedField<int32>* public_dependency,
RepeatedField<int32>* weak_dependency,
const LocationRecorder& root_location) {
DO(Consume("import"));
if (LookingAt("public")) {
LocationRecorder location(
root_location, FileDescriptorProto::kPublicDependencyFieldNumber,
public_dependency->size());
DO(Consume("public"));
*public_dependency->Add() = dependency->size();
} else if (LookingAt("weak")) {
LocationRecorder location(
root_location, FileDescriptorProto::kWeakDependencyFieldNumber,
weak_dependency->size());
DO(Consume("weak"));
*weak_dependency->Add() = dependency->size();
}
{
LocationRecorder location(root_location,
FileDescriptorProto::kDependencyFieldNumber,
index);
DO(ConsumeString(import_filename,
dependency->size());
DO(ConsumeString(dependency->Add(),
"Expected a string naming the file to import."));
}
DO(Consume(";"));
return true;
}
bool Parser::ParseOption(Message* options,
const LocationRecorder& options_location) {
DO(Consume("option"));
DO(ParseOptionAssignment(options, options_location));
DO(Consume(";"));
location.EndAt(input_->previous());
DO(ConsumeEndOfDeclaration(";", &location));
}
return true;
}

View File

@ -116,6 +116,8 @@ class LIBPROTOBUF_EXPORT Parser {
}
private:
class LocationRecorder;
// =================================================================
// Error recovery helpers
@ -164,6 +166,8 @@ class LIBPROTOBUF_EXPORT Parser {
bool ConsumeIdentifier(string* output, const char* error);
// Consume an integer and store its value in "output".
bool ConsumeInteger(int* output, const char* error);
// Consume a signed integer and store its value in "output".
bool ConsumeSignedInteger(int* output, const char* error);
// Consume a 64-bit integer and store its value in "output". If the value
// is greater than max_value, an error will be reported.
bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error);
@ -173,6 +177,20 @@ class LIBPROTOBUF_EXPORT Parser {
// Consume a string literal and store its (unescaped) value in "output".
bool ConsumeString(string* output, const char* error);
// Consume a token representing the end of the statement. Comments between
// this token and the next will be harvested for documentation. The given
// LocationRecorder should refer to the declaration that was just parsed;
// it will be populated with these comments.
//
// TODO(kenton): The LocationRecorder is const because historically locations
// have been passed around by const reference, for no particularly good
// reason. We should probably go through and change them all to mutable
// pointer to make this more intuitive.
bool TryConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location);
bool ConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location);
// -----------------------------------------------------------------
// Error logging helpers
@ -227,6 +245,14 @@ class LIBPROTOBUF_EXPORT Parser {
void RecordLegacyLocation(const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location);
// Attaches leading and trailing comments to the location. The two strings
// will be swapped into place, so after this is called *leading and
// *trailing will be empty.
//
// TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for
// why this is const.
void AttachComments(string* leading, string* trailing) const;
private:
Parser* parser_;
SourceCodeInfo::Location* location_;
@ -265,9 +291,10 @@ class LIBPROTOBUF_EXPORT Parser {
const LocationRecorder& service_location);
bool ParsePackage(FileDescriptorProto* file,
const LocationRecorder& root_location);
bool ParseImport(string* import_filename,
const LocationRecorder& root_location,
int index);
bool ParseImport(RepeatedPtrField<string>* dependency,
RepeatedField<int32>* public_dependency,
RepeatedField<int32>* weak_dependency,
const LocationRecorder& root_location);
bool ParseOption(Message* options,
const LocationRecorder& options_location);
@ -329,6 +356,12 @@ class LIBPROTOBUF_EXPORT Parser {
bool ParseServiceMethod(MethodDescriptorProto* method,
const LocationRecorder& method_location);
// Parse options of a single method or stream.
bool ParseOptions(const LocationRecorder& parent_location,
const int optionsFieldNumber,
Message* mutable_options);
// Parse "required", "optional", or "repeated" and fill in "label"
// with the value.
bool ParseLabel(FieldDescriptorProto::Label* label);
@ -351,11 +384,17 @@ class LIBPROTOBUF_EXPORT Parser {
bool ParseDefaultAssignment(FieldDescriptorProto* field,
const LocationRecorder& field_location);
enum OptionStyle {
OPTION_ASSIGNMENT, // just "name = value"
OPTION_STATEMENT // "option name = value;"
};
// Parse a single option name/value pair, e.g. "ctype = CORD". The name
// identifies a field of the given Message, and the value of that field
// is set to the parsed value.
bool ParseOptionAssignment(Message* options,
const LocationRecorder& options_location);
bool ParseOption(Message* options,
const LocationRecorder& options_location,
OptionStyle style);
// Parses a single part of a multipart option name. A multipart name consists
// of names separated by dots. Each name is either an identifier or a series
@ -387,6 +426,10 @@ class LIBPROTOBUF_EXPORT Parser {
bool stop_after_syntax_identifier_;
string syntax_identifier_;
// Leading doc comments for the next declaration. These are not complete
// yet; use ConsumeEndOfDeclaration() to get the complete comments.
string upcoming_doc_comments_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
};

View File

@ -56,7 +56,6 @@
#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace compiler {
@ -64,7 +63,7 @@ namespace compiler {
class CodeGenerator; // code_generator.h
// Implements main() for a protoc plugin exposing the given code generator.
int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
} // namespace compiler
} // namespace protobuf

View File

@ -1,14 +1,17 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/compiler/plugin.proto
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "google/protobuf/compiler/plugin.pb.h"
#include <algorithm>
#include <google/protobuf/stubs/common.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/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
@ -136,7 +139,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
"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);
"\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\tB"
",\n\034com.google.protobuf.compilerB\014PluginP"
"rotos", 445);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes);
CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest();
@ -155,7 +160,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
// ===================================================================
#ifndef _MSC_VER
@ -207,7 +211,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() {
}
const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_;
if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
return *default_instance_;
}
CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL;
@ -244,7 +249,8 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream(
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(),
this->file_to_generate(this->file_to_generate_size() - 1).data(),
this->file_to_generate(this->file_to_generate_size() - 1).length(),
::google::protobuf::internal::WireFormat::PARSE);
} else {
goto handle_uninterpreted;
@ -530,7 +536,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() {
}
const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() {
if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_;
if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
return *default_instance_;
}
CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL;
@ -859,7 +866,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() {
}
const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_;
if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
return *default_instance_;
}
CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL;

View File

@ -8,21 +8,22 @@
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 2004000
#if GOOGLE_PROTOBUF_VERSION < 2005000
#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 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#if 2005000 < 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/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/unknown_field_set.h>
#include "google/protobuf/descriptor.pb.h"
// @@protoc_insertion_point(includes)
@ -121,6 +122,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
inline void set_parameter(const char* value, size_t size);
inline ::std::string* mutable_parameter();
inline ::std::string* release_parameter();
inline void set_allocated_parameter(::std::string* parameter);
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int proto_file_size() const;
@ -221,6 +223,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
inline ::std::string* release_name();
inline void set_allocated_name(::std::string* name);
// optional string insertion_point = 2;
inline bool has_insertion_point() const;
@ -232,6 +235,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_insertion_point(const char* value, size_t size);
inline ::std::string* mutable_insertion_point();
inline ::std::string* release_insertion_point();
inline void set_allocated_insertion_point(::std::string* insertion_point);
// optional string content = 15;
inline bool has_content() const;
@ -243,6 +247,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_content(const char* value, size_t size);
inline ::std::string* mutable_content();
inline ::std::string* release_content();
inline void set_allocated_content(::std::string* content);
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
private:
@ -337,6 +342,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
inline void set_error(const char* value, size_t size);
inline ::std::string* mutable_error();
inline ::std::string* release_error();
inline void set_allocated_error(::std::string* error);
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int file_size() const;
@ -478,6 +484,18 @@ inline ::std::string* CodeGeneratorRequest::release_parameter() {
return temp;
}
}
inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) {
if (parameter_ != &::google::protobuf::internal::kEmptyString) {
delete parameter_;
}
if (parameter) {
set_has_parameter();
parameter_ = parameter;
} else {
clear_has_parameter();
parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int CodeGeneratorRequest::proto_file_size() const {
@ -565,6 +583,18 @@ inline ::std::string* CodeGeneratorResponse_File::release_name() {
return temp;
}
}
inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) {
if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
if (name) {
set_has_name();
name_ = name;
} else {
clear_has_name();
name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// optional string insertion_point = 2;
inline bool CodeGeneratorResponse_File::has_insertion_point() const {
@ -623,6 +653,18 @@ inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
return temp;
}
}
inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) {
if (insertion_point_ != &::google::protobuf::internal::kEmptyString) {
delete insertion_point_;
}
if (insertion_point) {
set_has_insertion_point();
insertion_point_ = insertion_point;
} else {
clear_has_insertion_point();
insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// optional string content = 15;
inline bool CodeGeneratorResponse_File::has_content() const {
@ -681,6 +723,18 @@ inline ::std::string* CodeGeneratorResponse_File::release_content() {
return temp;
}
}
inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) {
if (content_ != &::google::protobuf::internal::kEmptyString) {
delete content_;
}
if (content) {
set_has_content();
content_ = content;
} else {
clear_has_content();
content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// -------------------------------------------------------------------
@ -743,6 +797,18 @@ inline ::std::string* CodeGeneratorResponse::release_error() {
return temp;
}
}
inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) {
if (error_ != &::google::protobuf::internal::kEmptyString) {
delete error_;
}
if (error) {
set_has_error();
error_ = error;
} else {
clear_has_error();
error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int CodeGeneratorResponse::file_size() const {

View File

@ -45,6 +45,8 @@
// flag "--${NAME}_out" is passed to protoc.
package google.protobuf.compiler;
option java_package = "com.google.protobuf.compiler";
option java_outer_classname = "PluginProtos";
import "google/protobuf/descriptor.proto";

View File

@ -52,6 +52,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream.h>
@ -106,6 +107,12 @@ string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
const char kDescriptorKey[] = "DESCRIPTOR";
// Does the file have top-level enums?
inline bool HasTopLevelEnums(const FileDescriptor *file) {
return file->enum_type_count() > 0;
}
// Should we generate generic services for this file?
inline bool HasGenericServices(const FileDescriptor *file) {
return file->service_count() > 0 &&
@ -120,13 +127,21 @@ void PrintTopBoilerplate(
// TODO(robinson): Allow parameterization of Python version?
printer->Print(
"# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"\n"
"from google.protobuf import descriptor\n"
"from google.protobuf import message\n"
"from google.protobuf import reflection\n");
"# source: $filename$\n"
"\n",
"filename", file->name());
if (HasTopLevelEnums(file)) {
printer->Print(
"from google.protobuf.internal import enum_type_wrapper\n");
}
printer->Print(
"from google.protobuf import descriptor as _descriptor\n"
"from google.protobuf import message as _message\n"
"from google.protobuf import reflection as _reflection\n"
);
if (HasGenericServices(file)) {
printer->Print(
"from google.protobuf import service\n"
"from google.protobuf import service as _service\n"
"from google.protobuf import service_reflection\n");
}
@ -270,6 +285,11 @@ bool Generator::Generate(const FileDescriptor* file,
// since they need to call static RegisterExtension() methods on these
// classes.
FixForeignFieldsInExtensions();
// Descriptor options may have custom extensions. These custom options
// can only be successfully parsed after we register corresponding
// extensions. Therefore we parse all options again here to recognize
// custom options that may be unknown when we define the descriptors.
FixAllDescriptorOptions();
if (HasGenericServices(file)) {
PrintServices();
}
@ -288,6 +308,13 @@ void Generator::PrintImports() const {
module_name);
}
printer_->Print("\n");
// Print public imports.
for (int i = 0; i < file_->public_dependency_count(); ++i) {
string module_name = ModuleName(file_->public_dependency(i)->name());
printer_->Print("from $module$ import *\n", "module", module_name);
}
printer_->Print("\n");
}
// Prints the single file descriptor for this file.
@ -297,7 +324,7 @@ void Generator::PrintFileDescriptor() const {
m["name"] = file_->name();
m["package"] = file_->package();
const char file_descriptor_template[] =
"$descriptor_name$ = descriptor.FileDescriptor(\n"
"$descriptor_name$ = _descriptor.FileDescriptor(\n"
" name='$name$',\n"
" package='$package$',\n";
printer_->Print(m, file_descriptor_template);
@ -321,6 +348,11 @@ void Generator::PrintTopLevelEnums() const {
for (int i = 0; i < file_->enum_type_count(); ++i) {
const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
PrintEnum(enum_descriptor);
printer_->Print("$name$ = "
"enum_type_wrapper.EnumTypeWrapper($descriptor_name$)",
"name", enum_descriptor.name(),
"descriptor_name",
ModuleLevelDescriptorName(enum_descriptor));
printer_->Print("\n");
for (int j = 0; j < enum_descriptor.value_count(); ++j) {
@ -355,7 +387,7 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
m["full_name"] = enum_descriptor.full_name();
m["file"] = kDescriptorKey;
const char enum_descriptor_template[] =
"$descriptor_name$ = descriptor.EnumDescriptor(\n"
"$descriptor_name$ = _descriptor.EnumDescriptor(\n"
" name='$name$',\n"
" full_name='$full_name$',\n"
" filename=None,\n"
@ -436,7 +468,7 @@ void Generator::PrintServiceDescriptor(
descriptor.options().SerializeToString(&options_string);
printer_->Print(
"$service_name$ = descriptor.ServiceDescriptor(\n",
"$service_name$ = _descriptor.ServiceDescriptor(\n",
"service_name", service_name);
printer_->Indent();
map<string, string> m;
@ -459,7 +491,6 @@ void Generator::PrintServiceDescriptor(
printer_->Print("methods=[\n");
for (int i = 0; i < descriptor.method_count(); ++i) {
const MethodDescriptor* method = descriptor.method(i);
string options_string;
method->options().SerializeToString(&options_string);
m.clear();
@ -470,7 +501,7 @@ void Generator::PrintServiceDescriptor(
m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
m["options_value"] = OptionsValue("MethodOptions", options_string);
printer_->Print("descriptor.MethodDescriptor(\n");
printer_->Print("_descriptor.MethodDescriptor(\n");
printer_->Indent();
printer_->Print(
m,
@ -491,7 +522,7 @@ void Generator::PrintServiceDescriptor(
void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
// Print the service.
printer_->Print("class $class_name$(service.Service):\n",
printer_->Print("class $class_name$(_service.Service):\n",
"class_name", descriptor.name());
printer_->Indent();
printer_->Print(
@ -523,7 +554,7 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
PrintNestedDescriptors(message_descriptor);
printer_->Print("\n");
printer_->Print("$descriptor_name$ = descriptor.Descriptor(\n",
printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n",
"descriptor_name",
ModuleLevelDescriptorName(message_descriptor));
printer_->Indent();
@ -618,10 +649,10 @@ void Generator::PrintMessages() const {
// Mutually recursive with PrintNestedMessages().
void Generator::PrintMessage(
const Descriptor& message_descriptor) const {
printer_->Print("class $name$(message.Message):\n", "name",
printer_->Print("class $name$(_message.Message):\n", "name",
message_descriptor.name());
printer_->Indent();
printer_->Print("__metaclass__ = reflection.GeneratedProtocolMessageType\n");
printer_->Print("__metaclass__ = _reflection.GeneratedProtocolMessageType\n");
PrintNestedMessages(message_descriptor);
map<string, string> m;
m["descriptor_key"] = kDescriptorKey;
@ -779,6 +810,7 @@ void Generator::FixForeignFieldsInExtensions() const {
for (int i = 0; i < file_->message_type_count(); ++i) {
FixForeignFieldsInNestedExtensions(*file_->message_type(i));
}
printer_->Print("\n");
}
void Generator::FixForeignFieldsInExtension(
@ -829,7 +861,7 @@ void Generator::PrintEnumValueDescriptor(
m["options"] = OptionsValue("EnumValueOptions", options_string);
printer_->Print(
m,
"descriptor.EnumValueDescriptor(\n"
"_descriptor.EnumValueDescriptor(\n"
" name='$name$', index=$index$, number=$number$,\n"
" options=$options$,\n"
" type=None)");
@ -843,7 +875,7 @@ string Generator::OptionsValue(
return "None";
} else {
string full_class_name = "descriptor_pb2." + class_name;
return "descriptor._ParseOptions(" + full_class_name + "(), '"
return "_descriptor._ParseOptions(" + full_class_name + "(), '"
+ CEscape(serialized_options)+ "')";
}
}
@ -869,7 +901,7 @@ 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"
"_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"
@ -1000,6 +1032,125 @@ void Generator::PrintSerializedPbInterval(
"serialized_end", SimpleItoa(offset + sp.size()));
}
namespace {
void PrintDescriptorOptionsFixingCode(const string& descriptor,
const string& options,
io::Printer* printer) {
// TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase
// in proto2 python runtime but it couldn't be used here because appengine
// uses a snapshot version of the library in which the new method is not
// yet present. After appengine has synced their runtime library, the code
// below should be cleaned up to use _SetOptions().
printer->Print(
"$descriptor$.has_options = True\n"
"$descriptor$._options = $options$\n",
"descriptor", descriptor, "options", options);
}
} // namespace
// Prints expressions that set the options field of all descriptors.
void Generator::FixAllDescriptorOptions() const {
// Prints an expression that sets the file descriptor's options.
string file_options = OptionsValue(
"FileOptions", file_->options().SerializeAsString());
if (file_options != "None") {
PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
}
// Prints expressions that set the options for all top level enums.
for (int i = 0; i < file_->enum_type_count(); ++i) {
const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
FixOptionsForEnum(enum_descriptor);
}
// Prints expressions that set the options for all top level extensions.
for (int i = 0; i < file_->extension_count(); ++i) {
const FieldDescriptor& field = *file_->extension(i);
FixOptionsForField(field);
}
// Prints expressions that set the options for all messages, nested enums,
// nested extensions and message fields.
for (int i = 0; i < file_->message_type_count(); ++i) {
FixOptionsForMessage(*file_->message_type(i));
}
}
// Prints expressions that set the options for an enum descriptor and its
// value descriptors.
void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
string enum_options = OptionsValue(
"EnumOptions", enum_descriptor.options().SerializeAsString());
if (enum_options != "None") {
PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
}
for (int i = 0; i < enum_descriptor.value_count(); ++i) {
const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
string value_options = OptionsValue(
"EnumValueOptions", value_descriptor.options().SerializeAsString());
if (value_options != "None") {
PrintDescriptorOptionsFixingCode(
StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
value_descriptor.name().c_str()),
value_options, printer_);
}
}
}
// Prints expressions that set the options for field descriptors (including
// extensions).
void Generator::FixOptionsForField(
const FieldDescriptor& field) const {
string field_options = OptionsValue(
"FieldOptions", field.options().SerializeAsString());
if (field_options != "None") {
string field_name;
if (field.is_extension()) {
if (field.extension_scope() == NULL) {
// Top level extensions.
field_name = field.name();
} else {
field_name = FieldReferencingExpression(
field.extension_scope(), field, "extensions_by_name");
}
} else {
field_name = FieldReferencingExpression(
field.containing_type(), field, "fields_by_name");
}
PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
}
}
// Prints expressions that set the options for a message and all its inner
// types (nested messages, nested enums, extensions, fields).
void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
// Nested messages.
for (int i = 0; i < descriptor.nested_type_count(); ++i) {
FixOptionsForMessage(*descriptor.nested_type(i));
}
// Enums.
for (int i = 0; i < descriptor.enum_type_count(); ++i) {
FixOptionsForEnum(*descriptor.enum_type(i));
}
// Fields.
for (int i = 0; i < descriptor.field_count(); ++i) {
const FieldDescriptor& field = *descriptor.field(i);
FixOptionsForField(field);
}
// Extensions.
for (int i = 0; i < descriptor.extension_count(); ++i) {
const FieldDescriptor& field = *descriptor.extension(i);
FixOptionsForField(field);
}
// Message option for this message.
string message_options = OptionsValue(
"MessageOptions", descriptor.options().SerializeAsString());
if (message_options != "None") {
string descriptor_name = ModuleLevelDescriptorName(descriptor);
PrintDescriptorOptionsFixingCode(descriptor_name,
message_options,
printer_);
}
}
} // namespace python
} // namespace compiler
} // namespace protobuf

View File

@ -138,6 +138,11 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
void PrintSerializedPbInterval(
const DescriptorT& descriptor, DescriptorProtoT& proto) const;
void FixAllDescriptorOptions() const;
void FixOptionsForField(const FieldDescriptor& field) const;
void FixOptionsForEnum(const EnumDescriptor& descriptor) const;
void FixOptionsForMessage(const Descriptor& descriptor) const;
// Very coarse-grained lock to ensure that Generate() is reentrant.
// Guards file_, printer_ and file_descriptor_serialized_.
mutable Mutex mutex_;

View File

@ -33,6 +33,7 @@
#include <google/protobuf/compiler/subprocess.h>
#include <algorithm>
#include <iostream>
#ifndef _WIN32
#include <errno.h>
@ -294,8 +295,8 @@ void Subprocess::Start(const string& program, SearchMode search_mode) {
int stdin_pipe[2];
int stdout_pipe[2];
pipe(stdin_pipe);
pipe(stdout_pipe);
GOOGLE_CHECK(pipe(stdin_pipe) != -1);
GOOGLE_CHECK(pipe(stdout_pipe) != -1);
char* argv[2] = { strdup(program.c_str()), NULL };
@ -323,9 +324,11 @@ void Subprocess::Start(const string& program, SearchMode search_mode) {
// 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]));
int ignored;
ignored = 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));
ignored = write(STDERR_FILENO, message, strlen(message));
(void) ignored;
// Must use _exit() rather than exit() to avoid flushing output buffers
// that will also be flushed by the parent.

View File

@ -53,7 +53,7 @@ class Message;
namespace compiler {
// Utility class for launching sub-processes.
class Subprocess {
class LIBPROTOC_EXPORT Subprocess {
public:
Subprocess();
~Subprocess();

View File

@ -58,6 +58,10 @@
#include <vector>
#include <google/protobuf/stubs/common.h>
// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h.
#ifdef TYPE_BOOL
#undef TYPE_BOOL
#endif // TYPE_BOOL
namespace google {
namespace protobuf {
@ -89,6 +93,7 @@ class ServiceOptions;
class MethodOptions;
class FileOptions;
class UninterpretedOption;
class SourceCodeInfo;
// Defined in message.h
class Message;
@ -100,6 +105,20 @@ class FileDescriptorTables;
// Defined in unknown_field_set.h.
class UnknownField;
// NB, all indices are zero-based.
struct SourceLocation {
int start_line;
int end_line;
int start_column;
int end_column;
// Doc comments found at the source location.
// TODO(kenton): Maybe this struct should have been named SourceInfo or
// something instead. Oh well.
string leading_comments;
string trailing_comments;
};
// Describes a type of protocol message, or a particular group within a
// message. To obtain the Descriptor for a given message object, call
// Message::GetDescriptor(). Generated message classes also have a
@ -236,6 +255,13 @@ class LIBPROTOBUF_EXPORT Descriptor {
// this message type's scope.
const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
// Source Location ---------------------------------------------------
// Updates |*out_location| to the source location of the complete
// extent of this message declaration. Returns false and leaves
// |*out_location| unchanged iff location information was not available.
bool GetSourceLocation(SourceLocation* out_location) const;
private:
typedef MessageOptions OptionsType;
@ -243,6 +269,10 @@ class LIBPROTOBUF_EXPORT Descriptor {
// correct depth
void DebugString(int depth, string *contents) const;
// Walks up the descriptor tree to generate the source location path
// to this descriptor from the file root.
void GetLocationPath(vector<int>* output) const;
const string* name_;
const string* full_name_;
const FileDescriptor* file_;
@ -389,7 +419,9 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
const string& camelcase_name() const;
Type type() const; // Declared type of this field.
const char* type_name() const; // Name of the declared type.
CppType cpp_type() const; // C++ type of this field.
const char* cpp_type_name() const; // Name of the C++ type.
Label label() const; // optional/required/repeated
bool is_required() const; // shorthand for label() == LABEL_REQUIRED
@ -397,6 +429,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
bool is_repeated() const; // shorthand for label() == LABEL_REPEATED
bool is_packable() const; // shorthand for is_repeated() &&
// IsTypePackable(type())
bool is_packed() const; // shorthand for is_packable() &&
// options().packed()
// Index of this field within the message's field array, or the file or
// extension scope's extensions array.
@ -479,6 +513,13 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
// Return true iff [packed = true] is valid for fields of this type.
static inline bool IsTypePackable(Type field_type);
// Source Location ---------------------------------------------------
// Updates |*out_location| to the source location of the complete
// extent of this field declaration. Returns false and leaves
// |*out_location| unchanged iff location information was not available.
bool GetSourceLocation(SourceLocation* out_location) const;
private:
typedef FieldOptions OptionsType;
@ -490,6 +531,10 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
// types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped.
string DefaultValueAsString(bool quote_string_type) const;
// Walks up the descriptor tree to generate the source location path
// to this descriptor from the file root.
void GetLocationPath(vector<int>* output) const;
const string* name_;
const string* full_name_;
const string* lowercase_name_;
@ -527,6 +572,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
static const char * const kTypeToName[MAX_TYPE + 1];
static const char * const kCppTypeToName[MAX_CPPTYPE + 1];
static const char * const kLabelToName[MAX_LABEL + 1];
// Must be constructed using DescriptorPool.
@ -583,12 +630,23 @@ class LIBPROTOBUF_EXPORT EnumDescriptor {
// See Descriptor::DebugString().
string DebugString() const;
// Source Location ---------------------------------------------------
// Updates |*out_location| to the source location of the complete
// extent of this enum declaration. Returns false and leaves
// |*out_location| unchanged iff location information was not available.
bool GetSourceLocation(SourceLocation* out_location) const;
private:
typedef EnumOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(int depth, string *contents) const;
// Walks up the descriptor tree to generate the source location path
// to this descriptor from the file root.
void GetLocationPath(vector<int>* output) const;
const string* name_;
const string* full_name_;
const FileDescriptor* file_;
@ -650,12 +708,23 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptor {
// See Descriptor::DebugString().
string DebugString() const;
// Source Location ---------------------------------------------------
// Updates |*out_location| to the source location of the complete
// extent of this enum value declaration. Returns false and leaves
// |*out_location| unchanged iff location information was not available.
bool GetSourceLocation(SourceLocation* out_location) const;
private:
typedef EnumValueOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(int depth, string *contents) const;
// Walks up the descriptor tree to generate the source location path
// to this descriptor from the file root.
void GetLocationPath(vector<int>* output) const;
const string* name_;
const string* full_name_;
int number_;
@ -703,19 +772,29 @@ class LIBPROTOBUF_EXPORT ServiceDescriptor {
// Look up a MethodDescriptor by name.
const MethodDescriptor* FindMethodByName(const string& name) const;
// See Descriptor::CopyTo().
void CopyTo(ServiceDescriptorProto* proto) const;
// See Descriptor::DebugString().
string DebugString() const;
// Source Location ---------------------------------------------------
// Updates |*out_location| to the source location of the complete
// extent of this service declaration. Returns false and leaves
// |*out_location| unchanged iff location information was not available.
bool GetSourceLocation(SourceLocation* out_location) const;
private:
typedef ServiceOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(string *contents) const;
// Walks up the descriptor tree to generate the source location path
// to this descriptor from the file root.
void GetLocationPath(vector<int>* output) const;
const string* name_;
const string* full_name_;
const FileDescriptor* file_;
@ -768,12 +847,23 @@ class LIBPROTOBUF_EXPORT MethodDescriptor {
// See Descriptor::DebugString().
string DebugString() const;
// Source Location ---------------------------------------------------
// Updates |*out_location| to the source location of the complete
// extent of this method declaration. Returns false and leaves
// |*out_location| unchanged iff location information was not available.
bool GetSourceLocation(SourceLocation* out_location) const;
private:
typedef MethodOptions OptionsType;
// See Descriptor::DebugString().
void DebugString(int depth, string *contents) const;
// Walks up the descriptor tree to generate the source location path
// to this descriptor from the file root.
void GetLocationPath(vector<int>* output) const;
const string* name_;
const string* full_name_;
const ServiceDescriptor* service_;
@ -791,6 +881,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptor {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor);
};
// Describes a whole .proto file. To get the FileDescriptor for a compiled-in
// file, get the descriptor for something defined in that file and call
// descriptor->file(). Use DescriptorPool to construct your own descriptors.
@ -813,6 +904,22 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
// These are returned in the order they were defined in the .proto file.
const FileDescriptor* dependency(int index) const;
// The number of files public imported by this one.
// The public dependency list is a subset of the dependency list.
int public_dependency_count() const;
// Gets a public imported file by index, where 0 <= index <
// public_dependency_count().
// These are returned in the order they were defined in the .proto file.
const FileDescriptor* public_dependency(int index) const;
// The number of files that are imported for weak fields.
// The weak dependency list is a subset of the dependency list.
int weak_dependency_count() const;
// Gets a weak imported file by index, where 0 <= index <
// weak_dependency_count().
// These are returned in the order they were defined in the .proto file.
const FileDescriptor* weak_dependency(int index) const;
// Number of top-level message types defined in this file. (This does not
// include nested types.)
int message_type_count() const;
@ -866,12 +973,28 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
// See Descriptor::CopyTo().
// Notes:
// - This method does NOT copy source code information since it is relatively
// large and rarely needed. See CopySourceCodeInfoTo() below.
void CopyTo(FileDescriptorProto* proto) const;
// Write the source code information of this FileDescriptor into the given
// FileDescriptorProto. See CopyTo() above.
void CopySourceCodeInfoTo(FileDescriptorProto* proto) const;
// See Descriptor::DebugString().
string DebugString() const;
private:
// Source Location ---------------------------------------------------
// Updates |*out_location| to the source location of the complete
// extent of the declaration or declaration-part denoted by |path|.
// Returns false and leaves |*out_location| unchanged iff location
// information was not available. (See SourceCodeInfo for
// description of path encoding.)
bool GetSourceLocation(const vector<int>& path,
SourceLocation* out_location) const;
typedef FileOptions OptionsType;
const string* name_;
@ -879,6 +1002,10 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
const DescriptorPool* pool_;
int dependency_count_;
const FileDescriptor** dependencies_;
int public_dependency_count_;
int* public_dependencies_;
int weak_dependency_count_;
int* weak_dependencies_;
int message_type_count_;
Descriptor* message_types_;
int enum_type_count_;
@ -890,6 +1017,7 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
const FileOptions* options_;
const FileDescriptorTables* tables_;
const SourceCodeInfo* source_code_info_;
// IMPORTANT: If you add a new field, make sure to search for all instances
// of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in
// descriptor.cc and update them to initialize the field.
@ -899,6 +1027,8 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
friend class Descriptor;
friend class FieldDescriptor;
friend class EnumDescriptor;
friend class EnumValueDescriptor;
friend class MethodDescriptor;
friend class ServiceDescriptor;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor);
};
@ -1106,7 +1236,7 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// For internal use only: Gets a non-const pointer to the generated pool.
// This is called at static-initialization time only, so thread-safety is
// not a concern. If both an underlay and a fallback database are present,
// the fallback database takes precedence.
// the underlay takes precedence.
static DescriptorPool* internal_generated_pool();
// For internal use only: Changes the behavior of BuildFile() such that it
@ -1132,6 +1262,11 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
friend class FileDescriptor;
friend class DescriptorBuilder;
// Return true if the given name is a sub-symbol of any non-package
// descriptor that already exists in the descriptor pool. (The full
// definition of such types is already known.)
bool IsSubSymbolOfBuiltType(const string& name) const;
// Tries to find something in the fallback database and link in the
// corresponding proto file. Returns true if successful, in which case
// the caller should search for the thing again. These are declared
@ -1203,7 +1338,7 @@ PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range,
const Descriptor::ExtensionRange*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension,
const FieldDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions);
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
@ -1220,7 +1355,7 @@ PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key,
const FieldDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions);
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 )
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 )
@ -1240,13 +1375,13 @@ PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value,
const EnumValueDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions);
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int)
PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions);
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name)
@ -1254,24 +1389,25 @@ PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method,
const MethodDescriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions);
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions);
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, public_dependency_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_dependency_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int)
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions);
PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*)
@ -1342,10 +1478,18 @@ inline int MethodDescriptor::index() const {
return this - service_->methods_;
}
inline const char* FieldDescriptor::type_name() const {
return kTypeToName[type_];
}
inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
return kTypeToCppTypeMap[type_];
}
inline const char* FieldDescriptor::cpp_type_name() const {
return kCppTypeToName[kTypeToCppTypeMap[type_]];
}
inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) {
return kTypeToCppTypeMap[type];
}
@ -1361,6 +1505,16 @@ inline const FileDescriptor* FileDescriptor::dependency(int index) const {
return dependencies_[index];
}
inline const FileDescriptor* FileDescriptor::public_dependency(
int index) const {
return dependencies_[public_dependencies_[index]];
}
inline const FileDescriptor* FileDescriptor::weak_dependency(
int index) const {
return dependencies_[weak_dependencies_[index]];
}
} // namespace protobuf
} // namespace google

View File

@ -59,6 +59,11 @@ message FileDescriptorProto {
// Names of files imported by this file.
repeated string dependency = 3;
// Indexes of the public imported files in the dependency list above.
repeated int32 public_dependency = 10;
// Indexes of the weak imported files in the dependency list.
// For Google-internal migration only. Do not use.
repeated int32 weak_dependency = 11;
// All top-level definitions in this file.
repeated DescriptorProto message_type = 4;
@ -101,13 +106,13 @@ message FieldDescriptorProto {
// Order is weird for historical reasons.
TYPE_DOUBLE = 1;
TYPE_FLOAT = 2;
TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers
// take 10 bytes. Use TYPE_SINT64 if negative
// values are likely.
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
// negative values are likely.
TYPE_INT64 = 3;
TYPE_UINT64 = 4;
TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers
// take 10 bytes. Use TYPE_SINT32 if negative
// values are likely.
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
// negative values are likely.
TYPE_INT32 = 5;
TYPE_FIXED64 = 6;
TYPE_FIXED32 = 7;
TYPE_BOOL = 8;
@ -199,6 +204,7 @@ message MethodDescriptorProto {
optional MethodOptions options = 4;
}
// ===================================================================
// Options
@ -220,10 +226,15 @@ message MethodDescriptorProto {
// through 99999. It is up to you to ensure that you do not use the
// same number for multiple options.
// * For options which will be published and used publicly by multiple
// independent entities, e-mail kenton@google.com to reserve extension
// numbers. Simply tell me how many you need and I'll send you back a
// set of numbers to use -- there's no need to explain how you intend to
// use them. If this turns out to be popular, a web service will be set up
// independent entities, e-mail protobuf-global-extension-registry@google.com
// to reserve extension numbers. Simply provide your project name (e.g.
// Object-C plugin) and your porject website (if available) -- there's no need
// to explain how you intend to use them. Usually you only need one extension
// number. You can declare multiple options with only one extension number by
// putting them in a sub-message. See the Custom Options section of the docs
// for examples:
// http://code.google.com/apis/protocolbuffers/docs/proto.html#options
// If this turns out to be popular, a web service will be set up
// to automatically assign option numbers.
@ -266,6 +277,9 @@ message FileOptions {
}
optional OptimizeMode optimize_for = 9 [default=SPEED];
// Sets the Go package where structs generated from this .proto will be
// placed. There is no default.
optional string go_package = 11;
@ -344,6 +358,37 @@ message FieldOptions {
optional bool packed = 2;
// Should this field be parsed lazily? Lazy applies only to message-type
// fields. It means that when the outer message is initially parsed, the
// inner message's contents will not be parsed but instead stored in encoded
// form. The inner message will actually be parsed when it is first accessed.
//
// This is only a hint. Implementations are free to choose whether to use
// eager or lazy parsing regardless of the value of this option. However,
// setting this option true suggests that the protocol author believes that
// using lazy parsing on this field is worth the additional bookkeeping
// overhead typically needed to implement it.
//
// This option does not affect the public interface of any generated code;
// all method signatures remain the same. Furthermore, thread-safety of the
// interface is not affected by this option; const methods remain safe to
// call from multiple threads concurrently, while non-const methods continue
// to require exclusive access.
//
//
// Note that implementations may choose not to check required fields within
// a lazy sub-message. That is, calling IsInitialized() on the outher message
// may return true even if the inner message has missing required fields.
// This is necessary because otherwise the inner message would have to be
// parsed in order to perform the check, defeating the purpose of lazy
// parsing. An implementation which chooses not to check required fields
// must be consistent about it. That is, for any particular sub-message, the
// implementation must either *always* check its required fields, or *never*
// check its required fields, regardless of whether or not the message has
// been parsed.
optional bool lazy = 5 [default=false];
// 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
@ -364,6 +409,9 @@ message FieldOptions {
// TODO: Fully-implement this, then remove the "experimental_" prefix.
optional string experimental_map_key = 9;
// For Google-internal migration only. Do not use.
optional bool weak = 10 [default=false];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -373,6 +421,10 @@ message FieldOptions {
message EnumOptions {
// Set this option to false to disallow mapping different tag names to a same
// value.
optional bool allow_alias = 2 [default=true];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -416,6 +468,7 @@ message MethodOptions {
extensions 1000 to max;
}
// A message representing a option the parser does not recognize. This only
// appears in options protos created by the compiler::Parser class.
// DescriptorPool resolves these when building Descriptor objects. Therefore,
@ -527,7 +580,41 @@ message SourceCodeInfo {
// 1 to each before displaying to a user.
repeated int32 span = 2 [packed=true];
// TODO(kenton): Record comments appearing before and after the
// declaration.
// If this SourceCodeInfo represents a complete declaration, these are any
// comments appearing before and after the declaration which appear to be
// attached to the declaration.
//
// A series of line comments appearing on consecutive lines, with no other
// tokens appearing on those lines, will be treated as a single comment.
//
// Only the comment content is provided; comment markers (e.g. //) are
// stripped out. For block comments, leading whitespace and an asterisk
// will be stripped from the beginning of each line other than the first.
// Newlines are included in the output.
//
// Examples:
//
// optional int32 foo = 1; // Comment attached to foo.
// // Comment attached to bar.
// optional int32 bar = 2;
//
// optional string baz = 3;
// // Comment attached to baz.
// // Another line attached to baz.
//
// // Comment attached to qux.
// //
// // Another line attached to qux.
// optional double qux = 4;
//
// optional string corge = 5;
// /* Block comment attached
// * to corge. Leading asterisks
// * will be removed. */
// /* Block comment attached to
// * grault. */
// optional int32 grault = 6;
optional string leading_comments = 3;
optional string trailing_comments = 4;
}
}

View File

@ -39,7 +39,7 @@
#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/stl_util.h>
#include <google/protobuf/stubs/map-util.h>
namespace google {

View File

@ -41,6 +41,7 @@
#include <string>
#include <utility>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
namespace google {

View File

@ -36,13 +36,15 @@
#include <vector>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_custom_options.pb.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_custom_options.pb.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@ -1518,9 +1520,8 @@ TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
class MiscTest : public testing::Test {
protected:
// Function which makes a field of the given type just to find out what its
// cpp_type is.
FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
// Function which makes a field descriptor of the given type.
const FieldDescriptor* GetFieldDescriptorOfType(FieldDescriptor::Type type) {
FileDescriptorProto file_proto;
file_proto.set_name("foo.proto");
AddEmptyEnum(&file_proto, "DummyEnum");
@ -1538,19 +1539,62 @@ class MiscTest : public testing::Test {
}
// Build the descriptors and get the pointers.
DescriptorPool pool;
const FileDescriptor* file = pool.BuildFile(file_proto);
pool_.reset(new DescriptorPool());
const FileDescriptor* file = pool_->BuildFile(file_proto);
if (file != NULL &&
file->message_type_count() == 1 &&
file->message_type(0)->field_count() == 1) {
return file->message_type(0)->field(0)->cpp_type();
return file->message_type(0)->field(0);
} else {
return static_cast<FieldDescriptor::CppType>(0);
return NULL;
}
}
const char* GetTypeNameForFieldType(FieldDescriptor::Type type) {
const FieldDescriptor* field = GetFieldDescriptorOfType(type);
return field != NULL ? field->type_name() : "";
}
FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
const FieldDescriptor* field = GetFieldDescriptorOfType(type);
return field != NULL ? field->cpp_type() :
static_cast<FieldDescriptor::CppType>(0);
}
const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) {
const FieldDescriptor* field = GetFieldDescriptorOfType(type);
return field != NULL ? field->cpp_type_name() : "";
}
scoped_ptr<DescriptorPool> pool_;
};
TEST_F(MiscTest, TypeNames) {
// Test that correct type names are returned.
typedef FieldDescriptor FD; // avoid ugly line wrapping
EXPECT_STREQ("double" , GetTypeNameForFieldType(FD::TYPE_DOUBLE ));
EXPECT_STREQ("float" , GetTypeNameForFieldType(FD::TYPE_FLOAT ));
EXPECT_STREQ("int64" , GetTypeNameForFieldType(FD::TYPE_INT64 ));
EXPECT_STREQ("uint64" , GetTypeNameForFieldType(FD::TYPE_UINT64 ));
EXPECT_STREQ("int32" , GetTypeNameForFieldType(FD::TYPE_INT32 ));
EXPECT_STREQ("fixed64" , GetTypeNameForFieldType(FD::TYPE_FIXED64 ));
EXPECT_STREQ("fixed32" , GetTypeNameForFieldType(FD::TYPE_FIXED32 ));
EXPECT_STREQ("bool" , GetTypeNameForFieldType(FD::TYPE_BOOL ));
EXPECT_STREQ("string" , GetTypeNameForFieldType(FD::TYPE_STRING ));
EXPECT_STREQ("group" , GetTypeNameForFieldType(FD::TYPE_GROUP ));
EXPECT_STREQ("message" , GetTypeNameForFieldType(FD::TYPE_MESSAGE ));
EXPECT_STREQ("bytes" , GetTypeNameForFieldType(FD::TYPE_BYTES ));
EXPECT_STREQ("uint32" , GetTypeNameForFieldType(FD::TYPE_UINT32 ));
EXPECT_STREQ("enum" , GetTypeNameForFieldType(FD::TYPE_ENUM ));
EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
EXPECT_STREQ("sint32" , GetTypeNameForFieldType(FD::TYPE_SINT32 ));
EXPECT_STREQ("sint64" , GetTypeNameForFieldType(FD::TYPE_SINT64 ));
}
TEST_F(MiscTest, CppTypes) {
// Test that CPP types are assigned correctly.
@ -1576,6 +1620,31 @@ TEST_F(MiscTest, CppTypes) {
EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SINT64 ));
}
TEST_F(MiscTest, CppTypeNames) {
// Test that correct CPP type names are returned.
typedef FieldDescriptor FD; // avoid ugly line wrapping
EXPECT_STREQ("double" , GetCppTypeNameForFieldType(FD::TYPE_DOUBLE ));
EXPECT_STREQ("float" , GetCppTypeNameForFieldType(FD::TYPE_FLOAT ));
EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_INT64 ));
EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_UINT64 ));
EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_INT32 ));
EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_FIXED64 ));
EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_FIXED32 ));
EXPECT_STREQ("bool" , GetCppTypeNameForFieldType(FD::TYPE_BOOL ));
EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_STRING ));
EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP ));
EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE ));
EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_BYTES ));
EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_UINT32 ));
EXPECT_STREQ("enum" , GetCppTypeNameForFieldType(FD::TYPE_ENUM ));
EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
EXPECT_STREQ("int32" , GetCppTypeNameForFieldType(FD::TYPE_SINT32 ));
EXPECT_STREQ("int64" , GetCppTypeNameForFieldType(FD::TYPE_SINT64 ));
}
TEST_F(MiscTest, DefaultValues) {
// Test that setting default values works.
FileDescriptorProto file_proto;
@ -1670,7 +1739,7 @@ TEST_F(MiscTest, DefaultValues) {
message->field(3)->default_value_uint64());
EXPECT_EQ(4.5 , message->field(4)->default_value_float ());
EXPECT_EQ(10e100 , message->field(5)->default_value_double());
EXPECT_EQ(true , message->field(6)->default_value_bool ());
EXPECT_TRUE( message->field(6)->default_value_bool ());
EXPECT_EQ("hello" , message->field(7)->default_value_string());
EXPECT_EQ("\001\002\003" , message->field(8)->default_value_string());
EXPECT_EQ(enum_value_b , message->field(9)->default_value_enum ());
@ -1693,7 +1762,7 @@ TEST_F(MiscTest, DefaultValues) {
EXPECT_EQ(0 , message->field(14)->default_value_uint64());
EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
EXPECT_EQ(0.0 , message->field(16)->default_value_double());
EXPECT_EQ(false, message->field(17)->default_value_bool ());
EXPECT_FALSE( message->field(17)->default_value_bool ());
EXPECT_EQ("" , message->field(18)->default_value_string());
EXPECT_EQ("" , message->field(19)->default_value_string());
EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
@ -1739,13 +1808,31 @@ TEST_F(MiscTest, FieldOptions) {
}
// ===================================================================
enum DescriptorPoolMode {
NO_DATABASE,
FALLBACK_DATABASE
};
class AllowUnknownDependenciesTest : public testing::Test {
class AllowUnknownDependenciesTest
: public testing::TestWithParam<DescriptorPoolMode> {
protected:
DescriptorPoolMode mode() {
return GetParam();
}
virtual void SetUp() {
FileDescriptorProto foo_proto, bar_proto;
pool_.AllowUnknownDependencies();
switch (mode()) {
case NO_DATABASE:
pool_.reset(new DescriptorPool);
break;
case FALLBACK_DATABASE:
pool_.reset(new DescriptorPool(&db_));
break;
}
pool_->AllowUnknownDependencies();
ASSERT_TRUE(TextFormat::ParseFromString(
"name: 'foo.proto'"
@ -1776,13 +1863,13 @@ class AllowUnknownDependenciesTest : public testing::Test {
&bar_proto));
// Collect pointers to stuff.
bar_file_ = pool_.BuildFile(bar_proto);
bar_file_ = BuildFile(bar_proto);
ASSERT_TRUE(bar_file_ != NULL);
ASSERT_EQ(1, bar_file_->message_type_count());
bar_type_ = bar_file_->message_type(0);
foo_file_ = pool_.BuildFile(foo_proto);
foo_file_ = BuildFile(foo_proto);
ASSERT_TRUE(foo_file_ != NULL);
ASSERT_EQ(1, foo_file_->message_type_count());
@ -1794,6 +1881,20 @@ class AllowUnknownDependenciesTest : public testing::Test {
qux_field_ = foo_type_->field(2);
}
const FileDescriptor* BuildFile(const FileDescriptorProto& proto) {
switch (mode()) {
case NO_DATABASE:
return pool_->BuildFile(proto);
break;
case FALLBACK_DATABASE: {
EXPECT_TRUE(db_.Add(proto));
return pool_->FindFileByName(proto.name());
}
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return NULL;
}
const FileDescriptor* bar_file_;
const Descriptor* bar_type_;
const FileDescriptor* foo_file_;
@ -1802,10 +1903,11 @@ class AllowUnknownDependenciesTest : public testing::Test {
const FieldDescriptor* baz_field_;
const FieldDescriptor* qux_field_;
DescriptorPool pool_;
SimpleDescriptorDatabase db_; // used if in FALLBACK_DATABASE mode.
scoped_ptr<DescriptorPool> pool_;
};
TEST_F(AllowUnknownDependenciesTest, PlaceholderFile) {
TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
ASSERT_EQ(2, foo_file_->dependency_count());
EXPECT_EQ(bar_file_, foo_file_->dependency(0));
@ -1814,11 +1916,11 @@ TEST_F(AllowUnknownDependenciesTest, PlaceholderFile) {
EXPECT_EQ(0, baz_file->message_type_count());
// Placeholder files should not be findable.
EXPECT_EQ(bar_file_, pool_.FindFileByName(bar_file_->name()));
EXPECT_TRUE(pool_.FindFileByName(baz_file->name()) == NULL);
EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == NULL);
}
TEST_F(AllowUnknownDependenciesTest, PlaceholderTypes) {
TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
EXPECT_EQ(bar_type_, bar_field_->message_type());
@ -1836,12 +1938,12 @@ TEST_F(AllowUnknownDependenciesTest, PlaceholderTypes) {
EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name());
// Placeholder types should not be findable.
EXPECT_EQ(bar_type_, pool_.FindMessageTypeByName(bar_type_->full_name()));
EXPECT_TRUE(pool_.FindMessageTypeByName(baz_type->full_name()) == NULL);
EXPECT_TRUE(pool_.FindEnumTypeByName(qux_type->full_name()) == NULL);
EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == NULL);
EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == NULL);
}
TEST_F(AllowUnknownDependenciesTest, CopyTo) {
TEST_P(AllowUnknownDependenciesTest, CopyTo) {
// FieldDescriptor::CopyTo() should write non-fully-qualified type names
// for placeholder types which were not originally fully-qualified.
FieldDescriptorProto proto;
@ -1864,7 +1966,7 @@ TEST_F(AllowUnknownDependenciesTest, CopyTo) {
EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
}
TEST_F(AllowUnknownDependenciesTest, CustomOptions) {
TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
// Qux should still have the uninterpreted option attached.
ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
const UninterpretedOption& option =
@ -1873,7 +1975,7 @@ TEST_F(AllowUnknownDependenciesTest, CustomOptions) {
EXPECT_EQ("grault", option.name(0).name_part());
}
TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
// Test that we can extend an unknown type. This is slightly tricky because
// it means that the placeholder type must have an extension range.
@ -1884,7 +1986,7 @@ TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
"extension { extendee: 'UnknownType' name:'some_extension' number:123"
" label:LABEL_OPTIONAL type:TYPE_INT32 }",
&extension_proto));
const FileDescriptor* file = pool_.BuildFile(extension_proto);
const FileDescriptor* file = BuildFile(extension_proto);
ASSERT_TRUE(file != NULL);
@ -1896,7 +1998,7 @@ TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
}
TEST_F(AllowUnknownDependenciesTest, CustomOption) {
TEST_P(AllowUnknownDependenciesTest, CustomOption) {
// Test that we can use a custom option without having parsed
// descriptor.proto.
@ -1937,7 +2039,7 @@ TEST_F(AllowUnknownDependenciesTest, CustomOption) {
"}",
&option_proto));
const FileDescriptor* file = pool_.BuildFile(option_proto);
const FileDescriptor* file = BuildFile(option_proto);
ASSERT_TRUE(file != NULL);
// Verify that no extension options were set, but they were left as
@ -1949,6 +2051,81 @@ TEST_F(AllowUnknownDependenciesTest, CustomOption) {
EXPECT_EQ(2, file->options().uninterpreted_option_size());
}
TEST_P(AllowUnknownDependenciesTest,
UndeclaredDependencyTriggersBuildOfDependency) {
// Crazy case: suppose foo.proto refers to a symbol without declaring the
// dependency that finds it. In the event that the pool is backed by a
// DescriptorDatabase, the pool will attempt to find the symbol in the
// database. If successful, it will build the undeclared dependency to verify
// that the file does indeed contain the symbol. If that file fails to build,
// then its descriptors must be rolled back. However, we still want foo.proto
// to build successfully, since we are allowing unknown dependencies.
FileDescriptorProto undeclared_dep_proto;
// We make this file fail to build by giving it two fields with tag 1.
ASSERT_TRUE(TextFormat::ParseFromString(
"name: \"invalid_file_as_undeclared_dep.proto\" "
"package: \"undeclared\" "
"message_type: { "
" name: \"Quux\" "
" field { "
" name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
" }"
" field { "
" name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
" }"
"}",
&undeclared_dep_proto));
// We can't use the BuildFile() helper because we don't actually want to build
// it into the descriptor pool in the fallback database case: it just needs to
// be sitting in the database so that it gets built during the building of
// test.proto below.
switch (mode()) {
case NO_DATABASE: {
ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == NULL);
break;
}
case FALLBACK_DATABASE: {
ASSERT_TRUE(db_.Add(undeclared_dep_proto));
}
}
FileDescriptorProto test_proto;
ASSERT_TRUE(TextFormat::ParseFromString(
"name: \"test.proto\" "
"message_type: { "
" name: \"Corge\" "
" field { "
" name:'quux' number:1 label: LABEL_OPTIONAL "
" type_name:'undeclared.Quux' type: TYPE_MESSAGE "
" }"
"}",
&test_proto));
const FileDescriptor* file = BuildFile(test_proto);
ASSERT_TRUE(file != NULL);
GOOGLE_LOG(INFO) << file->DebugString();
EXPECT_EQ(0, file->dependency_count());
ASSERT_EQ(1, file->message_type_count());
const Descriptor* corge_desc = file->message_type(0);
ASSERT_EQ("Corge", corge_desc->name());
ASSERT_EQ(1, corge_desc->field_count());
const FieldDescriptor* quux_field = corge_desc->field(0);
ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
ASSERT_EQ("Quux", quux_field->message_type()->name());
ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
EXPECT_EQ("undeclared.Quux.placeholder.proto",
quux_field->message_type()->file()->name());
// The place holder type should not be findable.
ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == NULL);
}
INSTANTIATE_TEST_CASE_P(DatabaseSource,
AllowUnknownDependenciesTest,
testing::Values(NO_DATABASE, FALLBACK_DATABASE));
// ===================================================================
TEST(CustomOptions, OptionLocations) {
@ -1990,7 +2167,7 @@ TEST(CustomOptions, OptionTypes) {
options =
&protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
EXPECT_EQ(false , options->GetExtension(protobuf_unittest::bool_opt));
EXPECT_FALSE( options->GetExtension(protobuf_unittest::bool_opt));
EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::uint32_opt));
@ -2004,7 +2181,7 @@ TEST(CustomOptions, OptionTypes) {
options =
&protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
EXPECT_EQ(true , options->GetExtension(protobuf_unittest::bool_opt));
EXPECT_TRUE( options->GetExtension(protobuf_unittest::bool_opt));
EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt));
EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt));
EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
@ -2451,6 +2628,15 @@ TEST_F(ValidationErrorTest, UnknownDependency) {
"bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
}
TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
BuildFile("name: \"foo.proto\"");
BuildFileWithErrors(
"name: \"bar.proto\" "
"dependency: \"foo.proto\" "
"public_dependency: 1",
"bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
}
TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
// Used to crash: If we depend on a non-existent file and then refer to a
// package defined in a file that we didn't import, and that package is
@ -2829,6 +3015,164 @@ TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
"necessary import.\n");
}
TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
// Test for hidden dependencies.
//
// // bar.proto
// message Bar{}
//
// // forward.proto
// import "bar.proto"
//
// // foo.proto
// import "forward.proto"
// message Foo {
// optional Bar foo = 1; // Error, needs to import bar.proto explicitly.
// }
//
BuildFile(
"name: \"bar.proto\" "
"message_type { name: \"Bar\" }");
BuildFile(
"name: \"forward.proto\""
"dependency: \"bar.proto\"");
BuildFileWithErrors(
"name: \"foo.proto\" "
"dependency: \"forward.proto\" "
"message_type {"
" name: \"Foo\""
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
"}",
"foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
"which is not imported by \"foo.proto\". To use it here, please add the "
"necessary import.\n");
}
TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
// Test for public dependencies.
//
// // bar.proto
// message Bar{}
//
// // forward.proto
// import public "bar.proto"
//
// // foo.proto
// import "forward.proto"
// message Foo {
// optional Bar foo = 1; // Correct. "bar.proto" is public imported into
// // forward.proto, so when "foo.proto" imports
// // "forward.proto", it imports "bar.proto" too.
// }
//
BuildFile(
"name: \"bar.proto\" "
"message_type { name: \"Bar\" }");
BuildFile(
"name: \"forward.proto\""
"dependency: \"bar.proto\" "
"public_dependency: 0");
BuildFile(
"name: \"foo.proto\" "
"dependency: \"forward.proto\" "
"message_type {"
" name: \"Foo\""
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
"}");
}
TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
// Test for public dependencies.
//
// // bar.proto
// message Bar{}
//
// // forward.proto
// import public "bar.proto"
//
// // forward2.proto
// import public "forward.proto"
//
// // foo.proto
// import "forward2.proto"
// message Foo {
// optional Bar foo = 1; // Correct, public imports are transitive.
// }
//
BuildFile(
"name: \"bar.proto\" "
"message_type { name: \"Bar\" }");
BuildFile(
"name: \"forward.proto\""
"dependency: \"bar.proto\" "
"public_dependency: 0");
BuildFile(
"name: \"forward2.proto\""
"dependency: \"forward.proto\" "
"public_dependency: 0");
BuildFile(
"name: \"foo.proto\" "
"dependency: \"forward2.proto\" "
"message_type {"
" name: \"Foo\""
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
"}");
}
TEST_F(ValidationErrorTest,
FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
// Test for public dependencies.
//
// // bar.proto
// message Bar{}
//
// // forward.proto
// import "bar.proto"
//
// // forward2.proto
// import public "forward.proto"
//
// // foo.proto
// import "forward2.proto"
// message Foo {
// optional Bar foo = 1; // Error, the "bar.proto" is not public imported
// // into "forward.proto", so will not be imported
// // into either "forward2.proto" or "foo.proto".
// }
//
BuildFile(
"name: \"bar.proto\" "
"message_type { name: \"Bar\" }");
BuildFile(
"name: \"forward.proto\""
"dependency: \"bar.proto\"");
BuildFile(
"name: \"forward2.proto\""
"dependency: \"forward.proto\" "
"public_dependency: 0");
BuildFileWithErrors(
"name: \"foo.proto\" "
"dependency: \"forward2.proto\" "
"message_type {"
" name: \"Foo\""
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
"}",
"foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
"which is not imported by \"foo.proto\". To use it here, please add the "
"necessary import.\n");
}
TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
// The following should produce an error that Bar.Baz is not defined:
// message Bar { message Baz {} }
@ -3031,7 +3375,8 @@ TEST_F(ValidationErrorTest, InputTypeNotDefined) {
" method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
"}",
"foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n");
"foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
);
}
TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
@ -3044,7 +3389,8 @@ TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
" method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
"}",
"foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n");
"foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
);
}
TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
@ -3056,7 +3402,8 @@ TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
" method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
"}",
"foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n");
"foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
);
}
TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
@ -3069,9 +3416,11 @@ TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
" method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
"}",
"foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
"foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
);
}
TEST_F(ValidationErrorTest, IllegalPackedField) {
BuildFileWithErrors(
"name: \"foo.proto\" "
@ -3592,7 +3941,8 @@ TEST_F(ValidationErrorTest, RollbackAfterError) {
" }"
"}",
"foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n");
"foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
);
// Make sure that if we build the same file again with the error fixed,
// it works. If the above rollback was incomplete, then some symbols will
@ -3641,6 +3991,21 @@ TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]);
}
TEST_F(ValidationErrorTest, DisallowEnumAlias) {
BuildFileWithErrors(
"name: \"foo.proto\" "
"enum_type {"
" name: \"Bar\""
" value { name:\"ENUM_A\" number:0 }"
" value { name:\"ENUM_B\" number:0 }"
" options { allow_alias: false }"
"}",
"foo.proto: Bar: NUMBER: "
"\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
"If this is intended, set 'option allow_alias = true;' to the enum "
"definition.\n");
}
// ===================================================================
// DescriptorDatabase
@ -3659,16 +4024,23 @@ class DatabaseBackedPoolTest : public testing::Test {
virtual void SetUp() {
AddToDatabase(&database_,
"name: \"foo.proto\" "
"message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
"enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } "
"service { name:\"TestService\" } ");
"name: 'foo.proto' "
"message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
"enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
"service { name:'TestService' } ");
AddToDatabase(&database_,
"name: \"bar.proto\" "
"dependency: \"foo.proto\" "
"message_type { name:\"Bar\" } "
"extension { name:\"foo_ext\" extendee: \".Foo\" number:5 "
"name: 'bar.proto' "
"dependency: 'foo.proto' "
"message_type { name:'Bar' } "
"extension { name:'foo_ext' extendee: '.Foo' number:5 "
" label:LABEL_OPTIONAL type:TYPE_INT32 } ");
// Baz has an undeclared dependency on Foo.
AddToDatabase(&database_,
"name: 'baz.proto' "
"message_type { "
" name:'Baz' "
" field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
"}");
}
// We can't inject a file containing errors into a DescriptorPool, so we
@ -3907,6 +4279,33 @@ TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
error_collector.text_);
}
TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
// Check that we find and report undeclared dependencies on types that exist
// in the descriptor database but that have not not been built yet.
MockErrorCollector error_collector;
DescriptorPool pool(&database_, &error_collector);
EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
EXPECT_EQ(
"baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
"which is not imported by \"baz.proto\". To use it here, please add "
"the necessary import.\n",
error_collector.text_);
}
TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
// Make sure that all traces of bad types are removed from the pool. This used
// to be b/4529436, due to the fact that a symbol resolution failure could
// potentially cause another file to be recursively built, which would trigger
// a checkpoint _past_ possibly invalid symbols.
// Baz is defined in the database, but the file is invalid because it is
// missing a necessary import.
DescriptorPool pool(&database_);
EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
// Make sure that searching again for the file or the type fails.
EXPECT_TRUE(pool.FindFileByName("baz.proto") == NULL);
EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
}
TEST_F(DatabaseBackedPoolTest, UnittestProto) {
// Try to load all of unittest.proto from a DescriptorDatabase. This should
// thoroughly test all paths through DescriptorBuilder to insure that there
@ -3963,6 +4362,16 @@ TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == NULL);
EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == NULL);
EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == NULL);
EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == NULL);
EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == NULL);
EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == NULL);
EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == NULL);
EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == NULL);
EXPECT_EQ(0, call_counter.call_count_);
}
@ -4028,6 +4437,219 @@ TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
// ===================================================================
class AbortingErrorCollector : public DescriptorPool::ErrorCollector {
public:
AbortingErrorCollector() {}
virtual void AddError(
const string &filename,
const string &element_name,
const Message *message,
ErrorLocation location,
const string &error_message) {
GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << ": "
<< error_message;
}
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector);
};
// A source tree containing only one file.
class SingletonSourceTree : public compiler::SourceTree {
public:
SingletonSourceTree(const string& filename, const string& contents)
: filename_(filename), contents_(contents) {}
virtual io::ZeroCopyInputStream* Open(const string& filename) {
return filename == filename_ ?
new io::ArrayInputStream(contents_.data(), contents_.size()) : NULL;
}
private:
const string filename_;
const string contents_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
};
const char *const kSourceLocationTestInput =
"syntax = \"proto2\";\n"
"message A {\n"
" optional int32 a = 1;\n"
" message B {\n"
" required double b = 1;\n"
" }\n"
"}\n"
"enum Indecision {\n"
" YES = 1;\n"
" NO = 2;\n"
" MAYBE = 3;\n"
"}\n"
"service S {\n"
" rpc Method(A) returns (A.B);\n"
// Put an empty line here to make the source location range match.
"\n"
"}\n";
class SourceLocationTest : public testing::Test {
public:
SourceLocationTest()
: source_tree_("/test/test.proto", kSourceLocationTestInput),
db_(&source_tree_),
pool_(&db_, &collector_) {}
static string PrintSourceLocation(const SourceLocation &loc) {
return strings::Substitute("$0:$1-$2:$3",
1 + loc.start_line,
1 + loc.start_column,
1 + loc.end_line,
1 + loc.end_column);
}
private:
AbortingErrorCollector collector_;
SingletonSourceTree source_tree_;
compiler::SourceTreeDescriptorDatabase db_;
protected:
DescriptorPool pool_;
};
// TODO(adonovan): implement support for option fields and for
// subparts of declarations.
TEST_F(SourceLocationTest, GetSourceLocation) {
SourceLocation loc;
const FileDescriptor *file_desc =
GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
const Descriptor *a_desc = file_desc->FindMessageTypeByName("A");
EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
EXPECT_EQ("2:1-7:2", PrintSourceLocation(loc));
const Descriptor *a_b_desc = a_desc->FindNestedTypeByName("B");
EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
EXPECT_EQ("4:3-6:4", PrintSourceLocation(loc));
const EnumDescriptor *e_desc = file_desc->FindEnumTypeByName("Indecision");
EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
EXPECT_EQ("8:1-12:2", PrintSourceLocation(loc));
const EnumValueDescriptor *yes_desc = e_desc->FindValueByName("YES");
EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
EXPECT_EQ("9:3-9:13", PrintSourceLocation(loc));
const ServiceDescriptor *s_desc = file_desc->FindServiceByName("S");
EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
EXPECT_EQ("13:1-16:2", PrintSourceLocation(loc));
const MethodDescriptor *m_desc = s_desc->FindMethodByName("Method");
EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
EXPECT_EQ("14:3-14:31", PrintSourceLocation(loc));
}
// Missing SourceCodeInfo doesn't cause crash:
TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
SourceLocation loc;
const FileDescriptor *file_desc =
GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
FileDescriptorProto proto;
file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
EXPECT_FALSE(proto.has_source_code_info());
DescriptorPool bad1_pool(&pool_);
const FileDescriptor* bad1_file_desc =
GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
const Descriptor *bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
}
// Corrupt SourceCodeInfo doesn't cause crash:
TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
SourceLocation loc;
const FileDescriptor *file_desc =
GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
FileDescriptorProto proto;
file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
EXPECT_FALSE(proto.has_source_code_info());
SourceCodeInfo_Location *loc_msg =
proto.mutable_source_code_info()->add_location();
loc_msg->add_path(1);
loc_msg->add_path(2);
loc_msg->add_path(3);
loc_msg->add_span(4);
loc_msg->add_span(5);
loc_msg->add_span(6);
DescriptorPool bad2_pool(&pool_);
const FileDescriptor* bad2_file_desc =
GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
const Descriptor *bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
}
// ===================================================================
const char* const kCopySourceCodeInfoToTestInput =
"syntax = \"proto2\";\n"
"message Foo {}\n";
// Required since source code information is not preserved by
// FileDescriptorTest.
class CopySourceCodeInfoToTest : public testing::Test {
public:
CopySourceCodeInfoToTest()
: source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
db_(&source_tree_),
pool_(&db_, &collector_) {}
private:
AbortingErrorCollector collector_;
SingletonSourceTree source_tree_;
compiler::SourceTreeDescriptorDatabase db_;
protected:
DescriptorPool pool_;
};
TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
const FileDescriptor* file_desc =
GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
FileDescriptorProto file_desc_proto;
ASSERT_FALSE(file_desc_proto.has_source_code_info());
file_desc->CopyTo(&file_desc_proto);
EXPECT_FALSE(file_desc_proto.has_source_code_info());
}
TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
const FileDescriptor* file_desc =
GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
FileDescriptorProto file_desc_proto;
ASSERT_FALSE(file_desc_proto.has_source_code_info());
file_desc->CopySourceCodeInfoTo(&file_desc_proto);
const SourceCodeInfo& info = file_desc_proto.source_code_info();
ASSERT_EQ(3, info.location_size());
// Get the Foo message location
const SourceCodeInfo_Location& foo_location = info.location(1);
ASSERT_EQ(2, foo_location.path_size());
EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
EXPECT_EQ(0, foo_location.path(1)); // Foo is the first message defined
ASSERT_EQ(3, foo_location.span_size()); // Foo spans one line
EXPECT_EQ(1, foo_location.span(0)); // Foo is declared on line 1
EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0
EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14
}
// ===================================================================
} // namespace descriptor_unittest
} // namespace protobuf

View File

@ -123,7 +123,9 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
case FD::CPPTYPE_FLOAT : return sizeof(float );
case FD::CPPTYPE_BOOL : return sizeof(bool );
case FD::CPPTYPE_ENUM : return sizeof(int );
case FD::CPPTYPE_MESSAGE: return sizeof(Message*);
case FD::CPPTYPE_MESSAGE:
return sizeof(Message*);
case FD::CPPTYPE_STRING:
switch (field->options().ctype()) {
@ -178,7 +180,17 @@ class DynamicMessage : public Message {
// important (the prototype must be deleted *before* the offsets).
scoped_array<int> offsets;
scoped_ptr<const GeneratedMessageReflection> reflection;
scoped_ptr<const DynamicMessage> prototype;
// Don't use a scoped_ptr to hold the prototype: the destructor for
// DynamicMessage needs to know whether it is the prototype, and does so by
// looking back at this field. This would assume details about the
// implementation of scoped_ptr.
const DynamicMessage* prototype;
TypeInfo() : prototype(NULL) {}
~TypeInfo() {
delete prototype;
}
};
DynamicMessage(const TypeInfo* type_info);
@ -368,8 +380,8 @@ DynamicMessage::~DynamicMessage() {
break;
}
}
} else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) &&
!is_prototype()) {
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
if (!is_prototype()) {
Message* message = *reinterpret_cast<Message**>(field_ptr);
if (message != NULL) {
delete message;
@ -377,6 +389,7 @@ DynamicMessage::~DynamicMessage() {
}
}
}
}
void DynamicMessage::CrossLinkPrototypes() {
// This should only be called on the prototype message.
@ -403,7 +416,7 @@ void DynamicMessage::CrossLinkPrototypes() {
}
Message* DynamicMessage::New() const {
void* new_base = reinterpret_cast<uint8*>(operator new(type_info_->size));
void* new_base = operator new(type_info_->size);
memset(new_base, 0, type_info_->size);
return new(new_base) DynamicMessage(type_info_);
}
@ -465,7 +478,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
if (*target != NULL) {
// Already exists.
return (*target)->prototype.get();
return (*target)->prototype;
}
DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
@ -533,13 +546,13 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
void* base = operator new(size);
memset(base, 0, size);
DynamicMessage* prototype = new(base) DynamicMessage(type_info);
type_info->prototype.reset(prototype);
type_info->prototype = prototype;
// Construct the reflection object.
type_info->reflection.reset(
new GeneratedMessageReflection(
type_info->type,
type_info->prototype.get(),
type_info->prototype,
type_info->offsets.get(),
type_info->has_bits_offset,
type_info->unknown_fields_offset,

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