diff options
Diffstat (limited to 'src')
27 files changed, 4277 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 35f5c0c..de83a4e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -72,6 +72,7 @@ nobase_include_HEADERS = \ google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/cpp/cpp_generator.h \ google/protobuf/compiler/java/java_generator.h \ + google/protobuf/compiler/javamicro/javamicro_generator.h \ google/protobuf/compiler/python/python_generator.h lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la @@ -178,6 +179,23 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_primitive_field.h \ google/protobuf/compiler/java/java_service.cc \ google/protobuf/compiler/java/java_service.h \ + google/protobuf/compiler/javamicro/javamicro_enum.cc \ + google/protobuf/compiler/javamicro/javamicro_enum.h \ + google/protobuf/compiler/javamicro/javamicro_enum_field.cc \ + google/protobuf/compiler/javamicro/javamicro_enum_field.h \ + google/protobuf/compiler/javamicro/javamicro_field.cc \ + google/protobuf/compiler/javamicro/javamicro_field.h \ + google/protobuf/compiler/javamicro/javamicro_file.cc \ + google/protobuf/compiler/javamicro/javamicro_file.h \ + google/protobuf/compiler/javamicro/javamicro_generator.cc \ + google/protobuf/compiler/javamicro/javamicro_helpers.cc \ + google/protobuf/compiler/javamicro/javamicro_helpers.h \ + google/protobuf/compiler/javamicro/javamicro_message.cc \ + google/protobuf/compiler/javamicro/javamicro_message.h \ + google/protobuf/compiler/javamicro/javamicro_message_field.cc\ + google/protobuf/compiler/javamicro/javamicro_message_field.h \ + google/protobuf/compiler/javamicro/javamicro_primitive_field.cc\ + google/protobuf/compiler/javamicro/javamicro_primitive_field.h\ google/protobuf/compiler/python/python_generator.cc bin_PROGRAMS = protoc diff --git a/src/Makefile.in b/src/Makefile.in index daf81af..b48721f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -106,7 +106,11 @@ am_libprotoc_la_OBJECTS = code_generator.lo command_line_interface.lo \ cpp_string_field.lo java_enum.lo java_enum_field.lo \ java_extension.lo java_field.lo java_file.lo java_generator.lo \ java_helpers.lo java_message.lo java_message_field.lo \ - java_primitive_field.lo java_service.lo python_generator.lo + java_primitive_field.lo java_service.lo javamicro_enum.lo \ + javamicro_enum_field.lo javamicro_field.lo javamicro_file.lo \ + javamicro_generator.lo javamicro_helpers.lo \ + javamicro_message.lo javamicro_message_field.lo \ + javamicro_primitive_field.lo python_generator.lo libprotoc_la_OBJECTS = $(am_libprotoc_la_OBJECTS) libprotoc_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ @@ -298,6 +302,7 @@ am__nobase_include_HEADERS_DIST = google/protobuf/stubs/common.h \ google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/cpp/cpp_generator.h \ google/protobuf/compiler/java/java_generator.h \ + google/protobuf/compiler/javamicro/javamicro_generator.h \ google/protobuf/compiler/python/python_generator.h nobase_includeHEADERS_INSTALL = $(install_sh_DATA) HEADERS = $(nobase_include_HEADERS) @@ -491,6 +496,7 @@ nobase_include_HEADERS = \ google/protobuf/compiler/plugin.pb.h \ google/protobuf/compiler/cpp/cpp_generator.h \ google/protobuf/compiler/java/java_generator.h \ + google/protobuf/compiler/javamicro/javamicro_generator.h \ google/protobuf/compiler/python/python_generator.h lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la @@ -596,6 +602,23 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_primitive_field.h \ google/protobuf/compiler/java/java_service.cc \ google/protobuf/compiler/java/java_service.h \ + google/protobuf/compiler/javamicro/javamicro_enum.cc \ + google/protobuf/compiler/javamicro/javamicro_enum.h \ + google/protobuf/compiler/javamicro/javamicro_enum_field.cc \ + google/protobuf/compiler/javamicro/javamicro_enum_field.h \ + google/protobuf/compiler/javamicro/javamicro_field.cc \ + google/protobuf/compiler/javamicro/javamicro_field.h \ + google/protobuf/compiler/javamicro/javamicro_file.cc \ + google/protobuf/compiler/javamicro/javamicro_file.h \ + google/protobuf/compiler/javamicro/javamicro_generator.cc \ + google/protobuf/compiler/javamicro/javamicro_helpers.cc \ + google/protobuf/compiler/javamicro/javamicro_helpers.h \ + google/protobuf/compiler/javamicro/javamicro_message.cc \ + google/protobuf/compiler/javamicro/javamicro_message.h \ + google/protobuf/compiler/javamicro/javamicro_message_field.cc\ + google/protobuf/compiler/javamicro/javamicro_message_field.h \ + google/protobuf/compiler/javamicro/javamicro_primitive_field.cc\ + google/protobuf/compiler/javamicro/javamicro_primitive_field.h\ google/protobuf/compiler/python/python_generator.cc protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la @@ -925,6 +948,15 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_message_field.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_primitive_field.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_service.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_enum.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_enum_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_file.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_generator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_helpers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_message.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_message_field.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javamicro_primitive_field.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message_lite.Plo@am__quote@ @@ -1467,6 +1499,69 @@ java_service.lo: google/protobuf/compiler/java/java_service.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o java_service.lo `test -f 'google/protobuf/compiler/java/java_service.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_service.cc +javamicro_enum.lo: google/protobuf/compiler/javamicro/javamicro_enum.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_enum.lo -MD -MP -MF $(DEPDIR)/javamicro_enum.Tpo -c -o javamicro_enum.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_enum.Tpo $(DEPDIR)/javamicro_enum.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_enum.cc' object='javamicro_enum.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_enum.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum.cc + +javamicro_enum_field.lo: google/protobuf/compiler/javamicro/javamicro_enum_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_enum_field.lo -MD -MP -MF $(DEPDIR)/javamicro_enum_field.Tpo -c -o javamicro_enum_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum_field.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_enum_field.Tpo $(DEPDIR)/javamicro_enum_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_enum_field.cc' object='javamicro_enum_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_enum_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_enum_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_enum_field.cc + +javamicro_field.lo: google/protobuf/compiler/javamicro/javamicro_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_field.lo -MD -MP -MF $(DEPDIR)/javamicro_field.Tpo -c -o javamicro_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_field.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_field.Tpo $(DEPDIR)/javamicro_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_field.cc' object='javamicro_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_field.cc + +javamicro_file.lo: google/protobuf/compiler/javamicro/javamicro_file.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_file.lo -MD -MP -MF $(DEPDIR)/javamicro_file.Tpo -c -o javamicro_file.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_file.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_file.Tpo $(DEPDIR)/javamicro_file.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_file.cc' object='javamicro_file.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_file.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_file.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_file.cc + +javamicro_generator.lo: google/protobuf/compiler/javamicro/javamicro_generator.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_generator.lo -MD -MP -MF $(DEPDIR)/javamicro_generator.Tpo -c -o javamicro_generator.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_generator.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_generator.Tpo $(DEPDIR)/javamicro_generator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_generator.cc' object='javamicro_generator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_generator.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_generator.cc + +javamicro_helpers.lo: google/protobuf/compiler/javamicro/javamicro_helpers.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_helpers.lo -MD -MP -MF $(DEPDIR)/javamicro_helpers.Tpo -c -o javamicro_helpers.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_helpers.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_helpers.Tpo $(DEPDIR)/javamicro_helpers.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_helpers.cc' object='javamicro_helpers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_helpers.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_helpers.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_helpers.cc + +javamicro_message.lo: google/protobuf/compiler/javamicro/javamicro_message.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_message.lo -MD -MP -MF $(DEPDIR)/javamicro_message.Tpo -c -o javamicro_message.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_message.Tpo $(DEPDIR)/javamicro_message.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_message.cc' object='javamicro_message.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_message.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message.cc + +javamicro_message_field.lo: google/protobuf/compiler/javamicro/javamicro_message_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_message_field.lo -MD -MP -MF $(DEPDIR)/javamicro_message_field.Tpo -c -o javamicro_message_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message_field.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_message_field.Tpo $(DEPDIR)/javamicro_message_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_message_field.cc' object='javamicro_message_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_message_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_message_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_message_field.cc + +javamicro_primitive_field.lo: google/protobuf/compiler/javamicro/javamicro_primitive_field.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT javamicro_primitive_field.lo -MD -MP -MF $(DEPDIR)/javamicro_primitive_field.Tpo -c -o javamicro_primitive_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_primitive_field.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/javamicro_primitive_field.Tpo $(DEPDIR)/javamicro_primitive_field.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' object='javamicro_primitive_field.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o javamicro_primitive_field.lo `test -f 'google/protobuf/compiler/javamicro/javamicro_primitive_field.cc' || echo '$(srcdir)/'`google/protobuf/compiler/javamicro/javamicro_primitive_field.cc + python_generator.lo: google/protobuf/compiler/python/python_generator.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT python_generator.lo -MD -MP -MF $(DEPDIR)/python_generator.Tpo -c -o python_generator.lo `test -f 'google/protobuf/compiler/python/python_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_generator.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/python_generator.Tpo $(DEPDIR)/python_generator.Plo diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum.cc b/src/google/protobuf/compiler/javamicro/javamicro_enum.cc new file mode 100644 index 0000000..d74a149 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_enum.cc @@ -0,0 +1,96 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/javamicro/javamicro_params.h> +#include <google/protobuf/compiler/javamicro/javamicro_enum.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Params& params) + : params_(params), descriptor_(descriptor) { + for (int i = 0; i < descriptor_->value_count(); i++) { + const EnumValueDescriptor* value = descriptor_->value(i); + const EnumValueDescriptor* canonical_value = + descriptor_->FindValueByNumber(value->number()); + + if (value == canonical_value) { + canonical_values_.push_back(value); + } else { + Alias alias; + alias.value = value; + alias.canonical_value = canonical_value; + aliases_.push_back(alias); + } + } +} + +EnumGenerator::~EnumGenerator() {} + +void EnumGenerator::Generate(io::Printer* printer) { + printer->Print("// enum $classname$\n", "classname", descriptor_->name()); + for (int i = 0; i < canonical_values_.size(); i++) { + map<string, string> vars; + vars["name"] = canonical_values_[i]->name(); + vars["canonical_value"] = SimpleItoa(canonical_values_[i]->number()); + printer->Print(vars, + "public static final int $name$ = $canonical_value$;\n"); + } + + // ----------------------------------------------------------------- + + for (int i = 0; i < aliases_.size(); i++) { + map<string, string> vars; + vars["name"] = aliases_[i].value->name(); + vars["canonical_name"] = aliases_[i].canonical_value->name(); + printer->Print(vars, + "public static final int $name$ = $canonical_name$;\n"); + } + + printer->Print("\n"); +} + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum.h b/src/google/protobuf/compiler/javamicro/javamicro_enum.h new file mode 100644 index 0000000..9cf226f --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_enum.h @@ -0,0 +1,87 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ + +#include <string> +#include <vector> + +#include <google/protobuf/compiler/javamicro/javamicro_params.h> +#include <google/protobuf/descriptor.h> + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace javamicro { + +class EnumGenerator { + public: + explicit EnumGenerator(const EnumDescriptor* descriptor, const Params& params); + ~EnumGenerator(); + + void Generate(io::Printer* printer); + + private: + const Params& params_; + const EnumDescriptor* descriptor_; + + // The proto language allows multiple enum constants to have the same numeric + // value. Java, however, does not allow multiple enum constants to be + // considered equivalent. We treat the first defined constant for any + // given numeric value as "canonical" and the rest as aliases of that + // canonical value. + vector<const EnumValueDescriptor*> canonical_values_; + + struct Alias { + const EnumValueDescriptor* value; + const EnumValueDescriptor* canonical_value; + }; + vector<Alias> aliases_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc new file mode 100644 index 0000000..0ff49a3 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc @@ -0,0 +1,333 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/javamicro/javamicro_enum_field.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +namespace { + +// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of +// repeat code between this and the other field types. +void SetEnumVariables(const Params& params, + const FieldDescriptor* descriptor, map<string, string>* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["type"] = "int"; + (*variables)["default"] = DefaultValue(params, descriptor); + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + internal::WireFormat::TagSize(descriptor->number(), descriptor->type())); + (*variables)["message_name"] = descriptor->containing_type()->name(); +} + +} // namespace + +// =================================================================== + +EnumFieldGenerator:: +EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params) + : FieldGenerator(params), descriptor_(descriptor) { + SetEnumVariables(params, descriptor, &variables_); +} + +EnumFieldGenerator::~EnumFieldGenerator() {} + +void EnumFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private boolean has$capitalized_name$;\n" + "private int $name$_ = $default$;\n" + "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" + "public int get$capitalized_name$() { return $name$_; }\n" + "public $message_name$ set$capitalized_name$(int value) {\n" + " has$capitalized_name$ = true;\n" + " $name$_ = value;\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " has$capitalized_name$ = false;\n" + " $name$_ = $default$;\n" + " return this;\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "what is other??" + "if (other.has$capitalized_name$()) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + " set$capitalized_name$(input.readInt32());\n"); +} + +void EnumFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " output.writeInt32($number$, get$capitalized_name$());\n" + "}\n"); +} + +void EnumFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .computeInt32Size($number$, get$capitalized_name$());\n" + "}\n"); +} + +string EnumFieldGenerator::GetBoxedType() const { + return ClassName(params_, descriptor_->enum_type()); +} + +// =================================================================== + +RepeatedEnumFieldGenerator:: +RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params) + : FieldGenerator(params), descriptor_(descriptor) { + SetEnumVariables(params, descriptor, &variables_); + if (descriptor_->options().packed()) { + GOOGLE_LOG(FATAL) << "MicroRuntime does not support packed"; + } +} + +RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} + +void RepeatedEnumFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + if (params_.java_use_vector()) { + printer->Print(variables_, + "private java.util.Vector $name$_ = new java.util.Vector();\n" + "public java.util.Vector get$capitalized_name$List() {\n" + " return $name$_;\n" + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public int get$capitalized_name$(int index) {\n" + " return ((Integer)$name$_.elementAt(index)).intValue();\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, int value) {\n" + " $name$_.setElementAt(new Integer(value), index);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$(int value) {\n" + " $name$_.addElement(new Integer(value));\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_.removeAllElements();\n" + " return this;\n" + "}\n"); + } else { + printer->Print(variables_, + "private java.util.List<Integer> $name$_ =\n" + " java.util.Collections.emptyList();\n" + "public java.util.List<Integer> get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public int get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, int value) {\n" + " $name$_.set(index, value);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$(int value) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n" + " }\n" + " $name$_.add(value);\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_ = java.util.Collections.emptyList();\n" + " return this;\n" + "}\n"); + } + if (descriptor_->options().packed()) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize;\n"); + } +} + +void RepeatedEnumFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + if (params_.java_use_vector()) { + printer->Print(variables_, + "if (other.$name$_.size() != 0) {\n" + " for (int i = 0; i < other.$name$_.size(); i++)) {\n" + " result.$name$_.addElement(other.$name$_.elementAt(i));\n" + " }\n" + "}\n"); + } else { + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if (result.$name$_.isEmpty()) {\n" + " result.$name$_ = new java.util.ArrayList<java.lang.Integer>();\n" + " }\n" + " result.$name$_.addAll(other.$name$_);\n" + "}\n"); + } +} + +void RepeatedEnumFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + // If packed, set up the while loop + if (descriptor_->options().packed()) { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int oldLimit = input.pushLimit(length);\n" + "while(input.getBytesUntilLimit() > 0) {\n"); + printer->Indent(); + } + + // Read and store the enum + printer->Print(variables_, + " add$capitalized_name$(input.readInt32());\n"); + + if (descriptor_->options().packed()) { + printer->Outdent(); + printer->Print(variables_, + "}\n" + "input.popLimit(oldLimit);\n"); + } +} + +void RepeatedEnumFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n"); + if (params_.java_use_vector()) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " output.writeRawVarint32(get$capitalized_name$(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for ($type$ element : get$capitalized_name$List()) {\n" + " output.writeRawVarint32(element.getNumber());\n" + "}\n"); + } + } else { + if (params_.java_use_vector()) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " output.writeInt32($number$, (int)get$capitalized_name$(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (java.lang.Integer element : get$capitalized_name$List()) {\n" + " output.writeInt32($number$, element);\n" + "}\n"); + } + } +} + +void RepeatedEnumFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + if (params_.java_use_vector()) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .computeInt32SizeNoTag(get$capitalized_name$(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (java.lang.Integer element : get$capitalized_name$List()) {\n" + " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .computeInt32SizeNoTag(element);\n" + "}\n"); + } + printer->Print( + "size += dataSize;\n"); + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() != 0) {" + " size += $tag_size$;\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .computeRawVarint32Size(dataSize);\n" + "}"); + } else { + printer->Print(variables_, + "size += $tag_size$ * get$capitalized_name$List().size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +string RepeatedEnumFieldGenerator::GetBoxedType() const { + return ClassName(params_, descriptor_->enum_type()); +} + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h b/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h new file mode 100644 index 0000000..ab671c1 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h @@ -0,0 +1,94 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/javamicro/javamicro_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +class EnumFieldGenerator : public FieldGenerator { + public: + explicit EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params); + ~EnumFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); +}; + +class RepeatedEnumFieldGenerator : public FieldGenerator { + public: + explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params); + ~RepeatedEnumFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_field.cc new file mode 100644 index 0000000..a2ea4f9 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_field.cc @@ -0,0 +1,102 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/compiler/javamicro/javamicro_field.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/compiler/javamicro/javamicro_primitive_field.h> +#include <google/protobuf/compiler/javamicro/javamicro_enum_field.h> +#include <google/protobuf/compiler/javamicro/javamicro_message_field.h> +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +FieldGenerator::~FieldGenerator() {} + +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, const Params ¶ms) + : descriptor_(descriptor), + field_generators_( + new scoped_ptr<FieldGenerator>[descriptor->field_count()]), + extension_generators_( + new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) { + + // Construct all the FieldGenerators. + for (int i = 0; i < descriptor->field_count(); i++) { + field_generators_[i].reset(MakeGenerator(descriptor->field(i), params)); + } + for (int i = 0; i < descriptor->extension_count(); i++) { + extension_generators_[i].reset(MakeGenerator(descriptor->extension(i), params)); + } +} + +FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, const Params ¶ms) { + if (field->is_repeated()) { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new RepeatedMessageFieldGenerator(field, params); + case JAVATYPE_ENUM: + return new RepeatedEnumFieldGenerator(field, params); + default: + return new RepeatedPrimitiveFieldGenerator(field, params); + } + } else { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new MessageFieldGenerator(field, params); + case JAVATYPE_ENUM: + return new EnumFieldGenerator(field, params); + default: + return new PrimitiveFieldGenerator(field, params); + } + } +} + +FieldGeneratorMap::~FieldGeneratorMap() {} + +const FieldGenerator& FieldGeneratorMap::get( + const FieldDescriptor* field) const { + GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); + return *field_generators_[field->index()]; +} + +const FieldGenerator& FieldGeneratorMap::get_extension(int index) const { + return *extension_generators_[index]; +} + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_field.h b/src/google/protobuf/compiler/javamicro/javamicro_field.h new file mode 100644 index 0000000..1530778 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_field.h @@ -0,0 +1,98 @@ +// 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_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ + +#include <string> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/compiler/javamicro/javamicro_params.h> + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace javamicro { + +class FieldGenerator { + public: + //FieldGenerator() {} + FieldGenerator(const Params& params) : params_(params) {} + virtual ~FieldGenerator(); + + virtual void GenerateMembers(io::Printer* printer) const = 0; + virtual void GenerateMergingCode(io::Printer* printer) const = 0; + virtual void GenerateParsingCode(io::Printer* printer) const = 0; + virtual void GenerateSerializationCode(io::Printer* printer) const = 0; + virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; + + virtual string GetBoxedType() const = 0; + + protected: + const Params& params_; + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); +}; + +// Convenience class which constructs FieldGenerators for a Descriptor. +class FieldGeneratorMap { + public: + explicit FieldGeneratorMap(const Descriptor* descriptor, const Params ¶ms); + ~FieldGeneratorMap(); + + const FieldGenerator& get(const FieldDescriptor* field) const; + const FieldGenerator& get_extension(int index) const; + + private: + const Descriptor* descriptor_; + scoped_array<scoped_ptr<FieldGenerator> > field_generators_; + scoped_array<scoped_ptr<FieldGenerator> > extension_generators_; + + static FieldGenerator* MakeGenerator(const FieldDescriptor* field, const Params ¶ms); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_file.cc b/src/google/protobuf/compiler/javamicro/javamicro_file.cc new file mode 100644 index 0000000..0985538 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_file.cc @@ -0,0 +1,251 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/compiler/javamicro/javamicro_file.h> +#include <google/protobuf/compiler/javamicro/javamicro_enum.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/compiler/javamicro/javamicro_message.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +namespace { + +// Recursively searches the given message to see if it contains any extensions. +bool UsesExtensions(const Message& message) { + const Reflection* reflection = message.GetReflection(); + + // We conservatively assume that unknown fields are extensions. + if (reflection->GetUnknownFields(message).field_count() > 0) return true; + + vector<const FieldDescriptor*> fields; + reflection->ListFields(message, &fields); + + for (int i = 0; i < fields.size(); i++) { + if (fields[i]->is_extension()) return true; + + if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (fields[i]->is_repeated()) { + int size = reflection->FieldSize(message, fields[i]); + for (int j = 0; j < size; j++) { + const Message& sub_message = + reflection->GetRepeatedMessage(message, fields[i], j); + if (UsesExtensions(sub_message)) return true; + } + } else { + const Message& sub_message = reflection->GetMessage(message, fields[i]); + if (UsesExtensions(sub_message)) return true; + } + } + } + + return false; +} + +} // namespace + +FileGenerator::FileGenerator(const FileDescriptor* file, const Params& params) + : file_(file), + params_(params), + java_package_(FileJavaPackage(params, file)), + classname_(FileClassName(params, file)) {} + +FileGenerator::~FileGenerator() {} + +bool FileGenerator::Validate(string* error) { + // Check for extensions + FileDescriptorProto file_proto; + file_->CopyTo(&file_proto); + if (UsesExtensions(file_proto)) { + error->assign(file_->name()); + error->append( + ": Java MICRO_RUNTIME does not support extensions\""); + return false; + } + + // If there is no outer class name then there must be only + // message and no enums defined in the file scope. + if (!params_.has_java_outer_classname(file_->name())) { + if (file_->message_type_count() != 1) { + error->assign(file_->name()); + error->append( + ": Java MICRO_RUNTIME may only have 1 message if there is no 'option java_outer_classname'\""); + return false; + } + + if (file_->enum_type_count() != 0) { + error->assign(file_->name()); + error->append( + ": Java MICRO_RUNTIME must have an 'option java_outer_classname' if file scope enums are present\""); + return false; + } + } + + // Check that no class name matches the file's class name. This is a common + // problem that leads to Java compile errors that can be hard to understand. + // It's especially bad when using the java_multiple_files, since we would + // end up overwriting the outer class with one of the inner ones. + int found_fileName = 0; + for (int i = 0; i < file_->enum_type_count(); i++) { + if (file_->enum_type(i)->name() == classname_) { + found_fileName += 1; + } + } + for (int i = 0; i < file_->message_type_count(); i++) { + if (file_->message_type(i)->name() == classname_) { + found_fileName += 1; + } + } + if (file_->service_count() != 0) { + error->assign(file_->name()); + error->append( + ": Java MICRO_RUNTIME does not support services\""); + return false; + } + + if (found_fileName > 1) { + error->assign(file_->name()); + error->append( + ": Cannot generate Java output because there is more than one class name, \""); + error->append(classname_); + error->append( + "\", matches the name of one of the types declared inside it. " + "Please either rename the type or use the java_outer_classname " + "option to specify a different outer class name for the .proto file." + " -- FIX THIS MESSAGE"); + return false; + } + return true; +} + +void FileGenerator::Generate(io::Printer* printer) { + // We don't import anything because we refer to all classes by their + // fully-qualified names in the generated source. + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "\n"); + if (!java_package_.empty()) { + printer->Print( + "package $package$;\n" + "\n", + "package", java_package_); + } + + if (params_.has_java_outer_classname(file_->name())) { + printer->Print( + "public final class $classname$ {\n" + " private $classname$() {}\n", + "classname", classname_); + printer->Indent(); + } + + // ----------------------------------------------------------------- + + if (!params_.java_multiple_files()) { + for (int i = 0; i < file_->enum_type_count(); i++) { + EnumGenerator(file_->enum_type(i), params_).Generate(printer); + } + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator(file_->message_type(i), params_).Generate(printer); + } + } + + // Static variables. + for (int i = 0; i < file_->message_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(file_->message_type(i), params_).GenerateStaticVariables(printer); + } + + if (params_.has_java_outer_classname(file_->name())) { + printer->Outdent(); + printer->Print( + "}\n"); + } +} + +template<typename GeneratorClass, typename DescriptorClass> +static void GenerateSibling(const string& package_dir, + const string& java_package, + const DescriptorClass* descriptor, + OutputDirectory* output_directory, + vector<string>* file_list, + const Params& params) { + string filename = package_dir + descriptor->name() + ".java"; + file_list->push_back(filename); + + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->Open(filename)); + io::Printer printer(output.get(), '$'); + + printer.Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "\n"); + if (!java_package.empty()) { + printer.Print( + "package $package$;\n" + "\n", + "package", java_package); + } + + GeneratorClass(descriptor, params).Generate(&printer); +} + +void FileGenerator::GenerateSiblings(const string& package_dir, + OutputDirectory* output_directory, + vector<string>* file_list) { + if (params_.java_multiple_files()) { + for (int i = 0; i < file_->enum_type_count(); i++) { + GenerateSibling<EnumGenerator>(package_dir, java_package_, + file_->enum_type(i), + output_directory, file_list, params_); + } + for (int i = 0; i < file_->message_type_count(); i++) { + GenerateSibling<MessageGenerator>(package_dir, java_package_, + file_->message_type(i), + output_directory, file_list, params_); + } + } +} + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_file.h b/src/google/protobuf/compiler/javamicro/javamicro_file.h new file mode 100644 index 0000000..430172a --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_file.h @@ -0,0 +1,94 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ + +#include <string> +#include <vector> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/javamicro/javamicro_params.h> + +namespace google { +namespace protobuf { + class FileDescriptor; // descriptor.h + namespace io { + class Printer; // printer.h + } + namespace compiler { + class OutputDirectory; // code_generator.h + } +} + +namespace protobuf { +namespace compiler { +namespace javamicro { + +class FileGenerator { + public: + explicit FileGenerator(const FileDescriptor* file, const Params& params); + ~FileGenerator(); + + // Checks for problems that would otherwise lead to cryptic compile errors. + // Returns true if there are no problems, or writes an error description to + // the given string and returns false otherwise. + bool Validate(string* error); + + void Generate(io::Printer* printer); + + // If we aren't putting everything into one file, this will write all the + // files other than the outer file (i.e. one for each message, enum, and + // service type). + void GenerateSiblings(const string& package_dir, + OutputDirectory* output_directory, + vector<string>* file_list); + + const string& java_package() { return java_package_; } + const string& classname() { return classname_; } + + private: + const FileDescriptor* file_; + const Params& params_; + string java_package_; + string classname_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_generator.cc b/src/google/protobuf/compiler/javamicro/javamicro_generator.cc new file mode 100644 index 0000000..bfba8c5 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_generator.cc @@ -0,0 +1,209 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/compiler/javamicro/javamicro_params.h> +#include <google/protobuf/compiler/javamicro/javamicro_generator.h> +#include <google/protobuf/compiler/javamicro/javamicro_file.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +void UpdateParamsRecursively(Params& params, + const FileDescriptor* file) { + // Add any parameters for this file + if (file->options().has_java_outer_classname()) { + params.set_java_outer_classname( + file->name(), file->options().java_outer_classname()); + } + if (file->options().has_java_package()) { + params.set_java_package( + file->name(), file->options().java_package()); + } + + // Loop through all dependent files recursively + // adding dep + for (int i = 0; i < file->dependency_count(); i++) { + UpdateParamsRecursively(params, file->dependency(i)); + } +} + +JavaMicroGenerator::JavaMicroGenerator() {} +JavaMicroGenerator::~JavaMicroGenerator() {} + +bool JavaMicroGenerator::Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const { + vector<pair<string, string> > options; + +// GOOGLE_LOG(INFO) << "wink: JavaMicroGenerator::Generate INFO"; +// GOOGLE_LOG(WARNING) << "wink: JavaMicroGenerator::Generate WARNING"; +// GOOGLE_LOG(ERROR) << "wink: JavaMicroGenerator::Generate ERROR"; +// GOOGLE_LOG(FATAL) << "wink: JavaMicroGenerator::Generate"; + + ParseGeneratorParameter(parameter, &options); + + // ----------------------------------------------------------------- + // parse generator options + + // Name a file where we will write a list of generated file names, one + // per line. + string output_list_file; + Params params(file->name()); + + // Get options from the proto file + if (file->options().has_java_multiple_files()) { + params.set_java_multiple_files(file->options().java_multiple_files()); + } + + // Update per file params + UpdateParamsRecursively(params, file); + + // Replace any existing options with ones from command line + for (int i = 0; i < options.size(); i++) { + // GOOGLE_LOG(WARNING) << "first=" << options[i].first + // << " second=" << options[i].second; + if (options[i].first == "output_list_file") { + output_list_file = options[i].second; + } else if (options[i].first == "opt") { + if (options[i].second == "speed") { + params.set_optimization(JAVAMICRO_OPT_SPEED); + } else if (options[i].second == "space") { + params.set_optimization(JAVAMICRO_OPT_SPACE); + } else { + *error = "Unknown javamicro generator option: opt=" + + options[i].second + " expecting opt=space or opt=speed"; + return false; + } + } else if (options[i].first == "java_package") { + vector<string> parts; + SplitStringUsing(options[i].second, "|", &parts); + if (parts.size() != 2) { + *error = "Bad java_package, expecting filename|PackageName found '" + + options[i].second + "'"; + return false; + } + params.set_java_package(parts[0], parts[1]); + } else if (options[i].first == "java_outer_classname") { + vector<string> parts; + SplitStringUsing(options[i].second, "|", &parts); + if (parts.size() != 2) { + *error = "Bad java_outer_classname, " + "expecting filename|ClassName found '" + + options[i].second + "'"; + return false; + } + params.set_java_outer_classname(parts[0], parts[1]); + } else if (options[i].first == "java_multiple_files") { + params.set_java_multiple_files(options[i].second == "true"); + } else if (options[i].first == "java_use_vector") { + params.set_java_use_vector(options[i].second == "true"); + } else { + *error = "Ignore unknown javamicro generator option: " + options[i].first; + } + } + +#if 0 + GOOGLE_LOG(WARNING) << "optimization()=" << params.optimization(); + GOOGLE_LOG(WARNING) << "java_multiple_files()=" << params.java_multiple_files(); + GOOGLE_LOG(WARNING) << "java_use_vector()=" << params.java_use_vector(); + + GOOGLE_LOG(WARNING) << "----------"; + for (Params::NameMap::const_iterator it = params.java_packages().begin(); + it != params.java_packages().end(); + ++it) { + GOOGLE_LOG(WARNING) << "cn.filename=" << it->first << " package=" << it->second; + } + for (Params::NameMap::const_iterator it = params.java_outer_classnames().begin(); + it != params.java_outer_classnames().end(); + ++it) { + GOOGLE_LOG(WARNING) << "cn.filename=" << it->first << " classname=" << it->second; + } + GOOGLE_LOG(WARNING) << "=========="; + +#endif + + // ----------------------------------------------------------------- + + FileGenerator file_generator(file, params); + if (!file_generator.Validate(error)) { + return false; + } + + string package_dir = + StringReplace(file_generator.java_package(), ".", "/", true); + if (!package_dir.empty()) package_dir += "/"; + + vector<string> all_files; + + string java_filename = package_dir; + java_filename += file_generator.classname(); + java_filename += ".java"; + all_files.push_back(java_filename); + + // Generate main java file. + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->Open(java_filename)); + io::Printer printer(output.get(), '$'); + file_generator.Generate(&printer); + + // Generate sibling files. + file_generator.GenerateSiblings(package_dir, output_directory, &all_files); + + // Generate output list if requested. + if (!output_list_file.empty()) { + // Generate output list. This is just a simple text file placed in a + // deterministic location which lists the .java files being generated. + scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output( + output_directory->Open(output_list_file)); + io::Printer srclist_printer(srclist_raw_output.get(), '$'); + for (int i = 0; i < all_files.size(); i++) { + srclist_printer.Print("$filename$\n", "filename", all_files[i]); + } + } + + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_generator.h b/src/google/protobuf/compiler/javamicro/javamicro_generator.h new file mode 100644 index 0000000..a1c33b7 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_generator.h @@ -0,0 +1,72 @@ +// 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. +// +// Generates Java micro code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__ + +#include <string> +#include <google/protobuf/compiler/code_generator.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +// CodeGenerator implementation which generates Java micro code. If you create your +// own protocol compiler binary and you want it to support Java output for the +// micro runtime, you can do so by registering an instance of this CodeGenerator with +// the CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT JavaMicroGenerator : public CodeGenerator { + public: + JavaMicroGenerator(); + ~JavaMicroGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaMicroGenerator); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc b/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc new file mode 100644 index 0000000..11ba71a --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc @@ -0,0 +1,381 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <vector> + +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/compiler/javamicro/javamicro_params.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +const char kThickSeparator[] = + "// ===================================================================\n"; +const char kThinSeparator[] = + "// -------------------------------------------------------------------\n"; + +namespace { + +const char* kDefaultPackage = ""; + +const string& FieldName(const FieldDescriptor* field) { + // Groups are hacky: The name of the field is just the lower-cased name + // of the group type. In Java, though, we would like to retain the original + // capitalization of the type name. + if (field->type() == FieldDescriptor::TYPE_GROUP) { + return field->message_type()->name(); + } else { + return field->name(); + } +} + +string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) { + string result; + // Note: I distrust ctype.h due to locales. + for (int i = 0; i < input.size(); i++) { + if ('a' <= input[i] && input[i] <= 'z') { + if (cap_next_letter) { + result += input[i] + ('A' - 'a'); + } else { + result += input[i]; + } + cap_next_letter = false; + } else if ('A' <= input[i] && input[i] <= 'Z') { + if (i == 0 && !cap_next_letter) { + // Force first letter to lower-case unless explicitly told to + // capitalize it. + result += input[i] + ('a' - 'A'); + } else { + // Capital letters after the first are left as-is. + result += input[i]; + } + cap_next_letter = false; + } else if ('0' <= input[i] && input[i] <= '9') { + result += input[i]; + cap_next_letter = true; + } else { + cap_next_letter = true; + } + } + return result; +} + +} // namespace + +string UnderscoresToCamelCase(const FieldDescriptor* field) { + return UnderscoresToCamelCaseImpl(FieldName(field), false); +} + +string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { + return UnderscoresToCamelCaseImpl(FieldName(field), true); +} + +string UnderscoresToCamelCase(const MethodDescriptor* method) { + return UnderscoresToCamelCaseImpl(method->name(), false); +} + +string StripProto(const string& filename) { + if (HasSuffixString(filename, ".protodevel")) { + return StripSuffixString(filename, ".protodevel"); + } else { + return StripSuffixString(filename, ".proto"); + } +} + +string FileClassName(const Params& params, const FileDescriptor* file) { + string name; + + if (params.has_java_outer_classname(file->name())) { + name = params.java_outer_classname(file->name()); + } else { + if ((file->message_type_count() == 1) + || (file->enum_type_count() == 0)) { + // If no outer calls and only one message then + // use the message name as the file name + name = file->message_type(0)->name(); + } else { + // Use the filename it self with underscores removed + // and a CamelCase style name. + string basename; + string::size_type last_slash = file->name().find_last_of('/'); + if (last_slash == string::npos) { + basename = file->name(); + } else { + basename = file->name().substr(last_slash + 1); + } + name = UnderscoresToCamelCaseImpl(StripProto(basename), true); + } + } + + return name; +} + +string FileJavaPackage(const Params& params, const FileDescriptor* file) { + if (params.has_java_package(file->name())) { + return params.java_package(file->name()); + } else { + string result = kDefaultPackage; + if (!file->package().empty()) { + if (!result.empty()) result += '.'; + result += file->package(); + } + return result; + } +} + +string ToJavaName(const Params& params, const string& full_name, + const FileDescriptor* file) { + string result; + if (params.java_multiple_files()) { + result = FileJavaPackage(params, file); + } else { + result = ClassName(params, file); + } + if (file->package().empty()) { + result += '.'; + result += full_name; + } else { + // Strip the proto package from full_name since we've replaced it with + // the Java package. If there isn't an outer classname then strip it too. + int sizeToSkipPackageName = file->package().size(); + int sizeToSkipOutClassName; + if (params.has_java_outer_classname(file->name())) { + sizeToSkipOutClassName = 0; + } else { + sizeToSkipOutClassName = + full_name.find_first_of('.', sizeToSkipPackageName + 1); + } + int sizeToSkip = sizeToSkipOutClassName > 0 ? + sizeToSkipOutClassName : sizeToSkipPackageName; + string class_name = full_name.substr(sizeToSkip + 1); + if (class_name == FileClassName(params, file)) { + // Done class_name is already present. + } else { + result += '.'; + result += class_name; + } + } + return result; +} + +string ClassName(const Params& params, const FileDescriptor* descriptor) { + string result = FileJavaPackage(params, descriptor); + if (!result.empty()) result += '.'; + result += FileClassName(params, descriptor); + return result; +} + +string ClassName(const Params& params, const EnumDescriptor* descriptor) { + string result; + const FileDescriptor* file = descriptor->file(); + const string file_name = file->name(); + const string full_name = descriptor->full_name(); + int last_period = full_name.find_last_of('.'); + int first_period = full_name.find_first_of('.'); + + // Remove class_name as we're using public static final int's not enums + string base_name = full_name.substr(0, full_name.find_last_of('.')); + + if (!file->package().empty()) { + // Remove package name. + int offset = first_period; + if (last_period > first_period) { + // There was two or more periods so we need to remove this one too. + offset += 1; + } + base_name = base_name.substr(offset); + } + + if (params.has_java_package(file_name)) { + result += params.java_package(file_name); + } + if (params.has_java_outer_classname(file_name)) { + result += "."; + result += params.java_outer_classname(file_name); + } + if (!base_name.empty()) { + result += "."; + result += base_name; + } + return result; +} + +string FieldConstantName(const FieldDescriptor *field) { + string name = field->name() + "_FIELD_NUMBER"; + UpperString(&name); + return name; +} + +JavaType GetJavaType(FieldDescriptor::Type field_type) { + switch (field_type) { + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + return JAVATYPE_INT; + + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + return JAVATYPE_LONG; + + case FieldDescriptor::TYPE_FLOAT: + return JAVATYPE_FLOAT; + + case FieldDescriptor::TYPE_DOUBLE: + return JAVATYPE_DOUBLE; + + case FieldDescriptor::TYPE_BOOL: + return JAVATYPE_BOOLEAN; + + case FieldDescriptor::TYPE_STRING: + return JAVATYPE_STRING; + + case FieldDescriptor::TYPE_BYTES: + return JAVATYPE_BYTES; + + case FieldDescriptor::TYPE_ENUM: + return JAVATYPE_ENUM; + + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + return JAVATYPE_MESSAGE; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return JAVATYPE_INT; +} + +const char* BoxedPrimitiveTypeName(JavaType type) { + switch (type) { + case JAVATYPE_INT : return "java.lang.Integer"; + case JAVATYPE_LONG : return "java.lang.Long"; + case JAVATYPE_FLOAT : return "java.lang.Float"; + case JAVATYPE_DOUBLE : return "java.lang.Double"; + case JAVATYPE_BOOLEAN: return "java.lang.Boolean"; + case JAVATYPE_STRING : return "java.lang.String"; + case JAVATYPE_BYTES : return "com.google.protobuf.micro.ByteStringMicro"; + case JAVATYPE_ENUM : return "java.lang.Integer"; + case JAVATYPE_MESSAGE: return NULL; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +bool AllAscii(const string& text) { + for (int i = 0; i < text.size(); i++) { + if ((text[i] & 0x80) != 0) { + return false; + } + } + return true; +} + +string DefaultValue(const Params& params, const FieldDescriptor* field) { + // Switch on cpp_type since we need to know which default_value_* method + // of FieldDescriptor to call. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return SimpleItoa(field->default_value_int32()); + case FieldDescriptor::CPPTYPE_UINT32: + // Need to print as a signed int since Java has no unsigned. + return SimpleItoa(static_cast<int32>(field->default_value_uint32())); + case FieldDescriptor::CPPTYPE_INT64: + return SimpleItoa(field->default_value_int64()) + "L"; + case FieldDescriptor::CPPTYPE_UINT64: + return SimpleItoa(static_cast<int64>(field->default_value_uint64())) + + "L"; + case FieldDescriptor::CPPTYPE_DOUBLE: + return SimpleDtoa(field->default_value_double()) + "D"; + case FieldDescriptor::CPPTYPE_FLOAT: + return SimpleFtoa(field->default_value_float()) + "F"; + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() ? "true" : "false"; + case FieldDescriptor::CPPTYPE_STRING: + if (field->type() == FieldDescriptor::TYPE_BYTES) { + if (field->has_default_value()) { + // See comments in Internal.java for gory details. + return strings::Substitute( + "com.google.protobuf.micro.ByteStringMicro.copyFromUtf8(\"$0\")", + CEscape(field->default_value_string())); + } else { + return "com.google.protobuf.micro.ByteStringMicro.EMPTY"; + } + } else { + if (AllAscii(field->default_value_string())) { + // All chars are ASCII. In this case CEscape() works fine. + return "\"" + CEscape(field->default_value_string()) + "\""; + } else { + // See comments in Internal.java for gory details. + // BUG: Internal NOT SUPPORTED need to fix!! + return strings::Substitute( + "com.google.protobuf.micro.Internal.stringDefaultValue(\"$0\")", + CEscape(field->default_value_string())); + } + } + + case FieldDescriptor::CPPTYPE_ENUM: + return ClassName(params, field->enum_type()) + "." + + field->default_value_enum()->name(); + + case FieldDescriptor::CPPTYPE_MESSAGE: + return ClassName(params, field->message_type()) + ".getDefaultInstance()"; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return ""; +} + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_helpers.h b/src/google/protobuf/compiler/javamicro/javamicro_helpers.h new file mode 100644 index 0000000..eeddbf9 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_helpers.h @@ -0,0 +1,128 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ + +#include <string> +#include <google/protobuf/compiler/javamicro/javamicro_params.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +// Commonly-used separator comments. Thick is a line of '=', thin is a line +// of '-'. +extern const char kThickSeparator[]; +extern const char kThinSeparator[]; + +// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes +// "fooBarBaz" or "FooBarBaz", respectively. +string UnderscoresToCamelCase(const FieldDescriptor* field); +string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); + +// Similar, but for method names. (Typically, this merely has the effect +// of lower-casing the first letter of the name.) +string UnderscoresToCamelCase(const MethodDescriptor* method); + +// Strips ".proto" or ".protodevel" from the end of a filename. +string StripProto(const string& filename); + +// Gets the unqualified class name for the file. Each .proto file becomes a +// single Java class, with all its contents nested in that class. +string FileClassName(const Params& params, const FileDescriptor* file); + +// Returns the file's Java package name. +string FileJavaPackage(const Params& params, const FileDescriptor* file); + +// Converts the given fully-qualified name in the proto namespace to its +// fully-qualified name in the Java namespace, given that it is in the given +// file. +string ToJavaName(const Params& params, const string& full_name, + const FileDescriptor* file); + +// These return the fully-qualified class name corresponding to the given +// descriptor. +inline string ClassName(const Params& params, const Descriptor* descriptor) { + return ToJavaName(params, descriptor->full_name(), descriptor->file()); +} +string ClassName(const Params& params, const EnumDescriptor* descriptor); +inline string ClassName(const Params& params, + const ServiceDescriptor* descriptor) { + return ToJavaName(params, descriptor->full_name(), descriptor->file()); +} +inline string ExtensionIdentifierName(const Params& params, + const FieldDescriptor* descriptor) { + return ToJavaName(params, descriptor->full_name(), descriptor->file()); +} +string ClassName(const Params& params, const FileDescriptor* descriptor); + +// Get the unqualified name that should be used for a field's field +// number constant. +string FieldConstantName(const FieldDescriptor *field); + +enum JavaType { + JAVATYPE_INT, + JAVATYPE_LONG, + JAVATYPE_FLOAT, + JAVATYPE_DOUBLE, + JAVATYPE_BOOLEAN, + JAVATYPE_STRING, + JAVATYPE_BYTES, + JAVATYPE_ENUM, + JAVATYPE_MESSAGE +}; + +JavaType GetJavaType(FieldDescriptor::Type field_type); + +inline JavaType GetJavaType(const FieldDescriptor* field) { + return GetJavaType(field->type()); +} + +// Get the fully-qualified class name for a boxed primitive type, e.g. +// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message +// types. +const char* BoxedPrimitiveTypeName(JavaType type); + +string DefaultValue(const Params& params, const FieldDescriptor* field); + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message.cc b/src/google/protobuf/compiler/javamicro/javamicro_message.cc new file mode 100644 index 0000000..7fc6c3d --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_message.cc @@ -0,0 +1,474 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <algorithm> +#include <google/protobuf/stubs/hash.h> +#include <google/protobuf/compiler/javamicro/javamicro_message.h> +#include <google/protobuf/compiler/javamicro/javamicro_enum.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/descriptor.pb.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { + // Print the field's proto-syntax definition as a comment. We don't want to + // print group bodies so we cut off after the first line. + string def = field->DebugString(); + printer->Print("// $def$\n", + "def", def.substr(0, def.find_first_of('\n'))); +} + +struct FieldOrderingByNumber { + inline bool operator()(const FieldDescriptor* a, + const FieldDescriptor* b) const { + return a->number() < b->number(); + } +}; + +// Sort the fields of the given Descriptor by number into a new[]'d array +// and return it. +const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { + const FieldDescriptor** fields = + new const FieldDescriptor*[descriptor->field_count()]; + for (int i = 0; i < descriptor->field_count(); i++) { + fields[i] = descriptor->field(i); + } + sort(fields, fields + descriptor->field_count(), + FieldOrderingByNumber()); + return fields; +} + +// Get an identifier that uniquely identifies this type within the file. +// This is used to declare static variables related to this type at the +// outermost file scope. +string UniqueFileScopeIdentifier(const Descriptor* descriptor) { + return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); +} + +// Returns true if the message type has any required fields. If it doesn't, +// we can optimize out calls to its isInitialized() method. +// +// already_seen is used to avoid checking the same type multiple times +// (and also to protect against recursion). +static bool HasRequiredFields( + const Descriptor* type, + hash_set<const Descriptor*>* already_seen) { + if (already_seen->count(type) > 0) { + // The type is already in cache. This means that either: + // a. The type has no required fields. + // b. We are in the midst of checking if the type has required fields, + // somewhere up the stack. In this case, we know that if the type + // has any required fields, they'll be found when we return to it, + // and the whole call to HasRequiredFields() will return true. + // Therefore, we don't have to check if this type has required fields + // here. + return false; + } + already_seen->insert(type); + + // If the type has extensions, an extension with message type could contain + // required fields, so we have to be conservative and assume such an + // extension exists. + if (type->extension_range_count() > 0) return true; + + for (int i = 0; i < type->field_count(); i++) { + const FieldDescriptor* field = type->field(i); + if (field->is_required()) { + return true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (HasRequiredFields(field->message_type(), already_seen)) { + return true; + } + } + } + + return false; +} + +static bool HasRequiredFields(const Descriptor* type) { + hash_set<const Descriptor*> already_seen; + return HasRequiredFields(type, &already_seen); +} + +} // namespace + +// =================================================================== + +MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params) + : params_(params), + descriptor_(descriptor), + field_generators_(descriptor, params) { +} + +MessageGenerator::~MessageGenerator() {} + +void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { + // Generate static members for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(descriptor_->nested_type(i), params_) + .GenerateStaticVariables(printer); + } +} + +void MessageGenerator::GenerateStaticVariableInitializers( + io::Printer* printer) { + // Generate static member initializers for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + MessageGenerator(descriptor_->nested_type(i), params_) + .GenerateStaticVariableInitializers(printer); + } + + if (descriptor_->extension_count() != 0) { + GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n"; + } +} + +void MessageGenerator::Generate(io::Printer* printer) { + bool is_own_file = + params_.java_multiple_files() || ((descriptor_->containing_type() == NULL) + && !params_.has_java_outer_classname(descriptor_->file()->name())); + +#if 0 + GOOGLE_LOG(INFO) << "is_own_file=" << is_own_file; + GOOGLE_LOG(INFO) << "containing_type()=" << ((descriptor_->containing_type() == NULL) ? "NULL" : "not null"); + GOOGLE_LOG(INFO) << "java_multiple_files()=" << params_.java_multiple_files(); + GOOGLE_LOG(INFO) << "has_java_outer_classname()=" << params_.has_java_outer_classname(file_->name()); +#endif + + if ((descriptor_->extension_count() != 0) + || (descriptor_->extension_range_count() != 0)) { + GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n"; + } + + printer->Print( + "public $modifiers$ final class $classname$ extends\n" + " com.google.protobuf.micro.MessageMicro {\n", + "modifiers", is_own_file ? "" : "static", + "classname", descriptor_->name()); + printer->Indent(); + printer->Print( + "public $classname$() {}\n" + "\n", + "classname", descriptor_->name()); + + // Nested types and extensions + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer); + } + + // Fields + for (int i = 0; i < descriptor_->field_count(); i++) { + PrintFieldComment(printer, descriptor_->field(i)); + printer->Print("public static final int $constant_name$ = $number$;\n", + "constant_name", FieldConstantName(descriptor_->field(i)), + "number", SimpleItoa(descriptor_->field(i)->number())); + field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); + printer->Print("\n"); + } + + GenerateClear(printer); + GenerateIsInitialized(printer); + GenerateMessageSerializationMethods(printer); + GenerateMergeFromMethods(printer); + GenerateParseFromMethods(printer); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +// =================================================================== + +void MessageGenerator:: +GenerateMessageSerializationMethods(io::Printer* printer) { + scoped_array<const FieldDescriptor*> sorted_fields( + SortFieldsByNumber(descriptor_)); + + if (descriptor_->extension_range_count() != 0) { + GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n"; + } + + printer->Print( + "public void writeTo(com.google.protobuf.micro.CodedOutputStreamMicro output)\n" + " throws java.io.IOException {\n"); + printer->Indent(); + + // Output the fields in sorted order + for (int i = 0; i < descriptor_->field_count(); i++) { + GenerateSerializeOneField(printer, sorted_fields[i]); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n" + "private int cachedSize = -1;\n" + "public int getCachedSize() {\n" + " if (cachedSize < 0) {\n" + " // getSerializedSize sets cachedSize\n" + " getSerializedSize();\n" + " }\n" + " return cachedSize;\n" + "}\n" + "\n" + "public int getSerializedSize() {\n" + " int size = 0;\n"); + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); + } + + printer->Outdent(); + printer->Print( + " cachedSize = size;\n" + " return size;\n" + "}\n" + "\n"); +} + +void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) { + scoped_array<const FieldDescriptor*> sorted_fields( + SortFieldsByNumber(descriptor_)); + + if (params_.java_use_vector()) { + printer->Print( + "public com.google.protobuf.micro.MessageMicro mergeFrom(\n" + " com.google.protobuf.micro.CodedInputStreamMicro input)\n" + " throws java.io.IOException {\n", + "classname", descriptor_->name()); + } else { + printer->Print( + "public $classname$ mergeFrom(\n" + " com.google.protobuf.micro.CodedInputStreamMicro input)\n" + " throws java.io.IOException {\n", + "classname", descriptor_->name()); + } + printer->Indent(); + + printer->Print( + "while (true) {\n"); + printer->Indent(); + + printer->Print( + "int tag = input.readTag();\n" + "switch (tag) {\n"); + printer->Indent(); + + printer->Print( + "case 0:\n" // zero signals EOF / limit reached + " return this;\n" + "default: {\n" + " if (!parseUnknownField(input, tag)) {\n" + " return this;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + uint32 tag = WireFormatLite::MakeTag(field->number(), + WireFormat::WireTypeForField(field)); + + printer->Print( + "case $tag$: {\n", + "tag", SimpleItoa(tag)); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCode(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + } + + printer->Outdent(); + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" // switch (tag) + " }\n" // while (true) + "}\n" + "\n"); +} + +void MessageGenerator:: +GenerateParseFromMethods(io::Printer* printer) { + bool is_own_file = + descriptor_->containing_type() == NULL; + + // Note: These are separate from GenerateMessageSerializationMethods() + // because they need to be generated even for messages that are optimized + // for code size. + printer->Print( + "public $static$ $classname$ parseFrom(byte[] data)\n" + " throws com.google.protobuf.micro.InvalidProtocolBufferMicroException {\n" + " return ($classname$) (new $classname$().mergeFrom(data));\n" + "}\n" + "\n" + "public $static$ $classname$ parseFrom(\n" + " com.google.protobuf.micro.CodedInputStreamMicro input)\n" + " throws java.io.IOException {\n" + " return ($classname$) (new $classname$().mergeFrom(input));\n" + "}\n" + "\n", + "static", (is_own_file ? "static" : ""), + "classname", descriptor_->name()); +} + +void MessageGenerator::GenerateSerializeOneField( + io::Printer* printer, const FieldDescriptor* field) { + field_generators_.get(field).GenerateSerializationCode(printer); +} + +void MessageGenerator::GenerateClear(io::Printer* printer) { + printer->Print( + "public final $classname$ clear() {\n", + "classname", descriptor_->name()); + printer->Indent(); + + // Call clear for all of the fields. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + printer->Print( + "clear$name$();\n", + "name", UnderscoresToCapitalizedCamelCase(field)); + } + + printer->Outdent(); + printer->Print( + " cachedSize = -1;\n" + " return this;\n" + "}\n" + "\n"); +} + + +void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { + printer->Print( + "public final boolean isInitialized() {\n"); + printer->Indent(); + + // Check that all required fields in this message are set. + // TODO(kenton): We can optimize this when we switch to putting all the + // "has" fields into a single bitfield. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (field->is_required()) { + printer->Print( + "if (!has$name$) return false;\n", + "name", UnderscoresToCapitalizedCamelCase(field)); + } + } + + // Now check that all embedded messages are initialized. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + HasRequiredFields(field->message_type())) { + switch (field->label()) { + case FieldDescriptor::LABEL_REQUIRED: + printer->Print( + "if (!get$name$().isInitialized()) return false;\n", + "type", ClassName(params_, field->message_type()), + "name", UnderscoresToCapitalizedCamelCase(field)); + break; + case FieldDescriptor::LABEL_OPTIONAL: + printer->Print( + "if (has$name$()) {\n" + " if (!get$name$().isInitialized()) return false;\n" + "}\n", + "type", ClassName(params_, field->message_type()), + "name", UnderscoresToCapitalizedCamelCase(field)); + break; + case FieldDescriptor::LABEL_REPEATED: + if (params_.java_use_vector()) { + printer->Print( + "for (int i = 0; i < get$name$List().size(); i++) {\n" + " if (get$name$(i).isInitialized()) return false;\n" + "}\n", + "type", ClassName(params_, field->message_type()), + "name", UnderscoresToCapitalizedCamelCase(field)); + } else { + printer->Print( + "for ($type$ element : get$name$List()) {\n" + " if (!element.isInitialized()) return false;\n" + "}\n", + "type", ClassName(params_, field->message_type()), + "name", UnderscoresToCapitalizedCamelCase(field)); + } + break; + } + } + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "if (!extensionsAreInitialized()) return false;\n"); + } + + printer->Outdent(); + printer->Print( + " return true;\n" + "}\n" + "\n"); +} + +// =================================================================== + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message.h b/src/google/protobuf/compiler/javamicro/javamicro_message.h new file mode 100644 index 0000000..f44c7a7 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_message.h @@ -0,0 +1,93 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ + +#include <string> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/javamicro/javamicro_params.h> +#include <google/protobuf/compiler/javamicro/javamicro_field.h> + +namespace google { +namespace protobuf { + namespace io { + class Printer; // printer.h + } +} + +namespace protobuf { +namespace compiler { +namespace javamicro { + +class MessageGenerator { + public: + explicit MessageGenerator(const Descriptor* descriptor, const Params& params); + ~MessageGenerator(); + + // All static variables have to be declared at the top-level of the file + // so that we can control initialization order, which is important for + // DescriptorProto bootstrapping to work. + void GenerateStaticVariables(io::Printer* printer); + + // Output code which initializes the static variables generated by + // GenerateStaticVariables(). + void GenerateStaticVariableInitializers(io::Printer* printer); + + // Generate the class itself. + void Generate(io::Printer* printer); + + private: + void GenerateMessageSerializationMethods(io::Printer* printer); + void GenerateMergeFromMethods(io::Printer* printer); + void GenerateParseFromMethods(io::Printer* printer); + void GenerateSerializeOneField(io::Printer* printer, + const FieldDescriptor* field); + + void GenerateClear(io::Printer* printer); + void GenerateIsInitialized(io::Printer* printer); + + const Params& params_; + const Descriptor* descriptor_; + FieldGeneratorMap field_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc new file mode 100644 index 0000000..103c302 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc @@ -0,0 +1,302 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/javamicro/javamicro_message_field.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +namespace { + +// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of +// repeat code between this and the other field types. +void SetMessageVariables(const Params& params, + const FieldDescriptor* descriptor, map<string, string>* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["type"] = ClassName(params, descriptor->message_type()); + (*variables)["group_or_message"] = + (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? + "Group" : "Message"; + (*variables)["message_name"] = descriptor->containing_type()->name(); + //(*variables)["message_type"] = descriptor->message_type()->name(); +} + +} // namespace + +// =================================================================== + +MessageFieldGenerator:: +MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) + : FieldGenerator(params), descriptor_(descriptor) { + SetMessageVariables(params, descriptor, &variables_); +} + +MessageFieldGenerator::~MessageFieldGenerator() {} + +void MessageFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private boolean has$capitalized_name$;\n" +// "private $type$ $name$_ = null;\n" +// "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" +// "public $type$ get$capitalized_name$() { return $name$_; }\n" + "private $type$ $name$_ = null;\n" + "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" + "public $type$ get$capitalized_name$() { return $name$_; }\n" + "public $message_name$ set$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " has$capitalized_name$ = true;\n" + " $name$_ = value;\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " has$capitalized_name$ = false;\n" + " $name$_ = null;\n" + " return this;\n" + "}\n"); +} + +void MessageFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " merge$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void MessageFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$type$ value = new $type$();\n"); + + if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "input.readGroup(value, $number$);\n"); + } else { + printer->Print(variables_, + "input.readMessage(value);\n"); + } + + printer->Print(variables_, + "set$capitalized_name$(value);\n"); +} + +void MessageFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " output.write$group_or_message$($number$, get$capitalized_name$());\n" + "}\n"); +} + +void MessageFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" + "}\n"); +} + +string MessageFieldGenerator::GetBoxedType() const { + return ClassName(params_, descriptor_->message_type()); +} + +// =================================================================== + +RepeatedMessageFieldGenerator:: +RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) + : FieldGenerator(params), descriptor_(descriptor) { + SetMessageVariables(params, descriptor, &variables_); +} + +RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} + +void RepeatedMessageFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + if (params_.java_use_vector()) { + printer->Print(variables_, + "private java.util.Vector $name$_ = new java.util.Vector();\n" + "public java.util.Vector get$capitalized_name$List() {\n" + " return $name$_;\n" + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public $type$ get$capitalized_name$(int index) {\n" + " return ($type$) $name$_.elementAt(index);\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $name$_.setElementAt(value, index);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $name$_.addElement(value);\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_.removeAllElements();\n" + " return this;\n" + "}\n"); + } else { + printer->Print(variables_, + "private java.util.List<$type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + "public java.util.List<$type$> get$capitalized_name$List() {\n" + " return $name$_;\n" + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $name$_.set(index, value);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = new java.util.ArrayList<$type$>();\n" + " }\n" + " $name$_.add(value);\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_ = java.util.Collections.emptyList();\n" + " return this;\n" + "}\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + if (params_.java_use_vector()) { + printer->Print(variables_, + "if (other.$name$_.size() != 0) {\n" + " for (int i = 0; i < other.$name$_.size(); i++) {\n" + " result.$name$_.addElement(other.$name$_.elementAt(i));\n" + " }\n" + "}\n"); + } else { + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if (result.$name$_.isEmpty()) {\n" + " result.$name$_ = new java.util.ArrayList<$type$>();\n" + " }\n" + " result.$name$_.addAll(other.$name$_);\n" + "}\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$type$ value = new $type$();\n"); + + if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "input.readGroup(value, $number$);\n"); + } else { + printer->Print(variables_, + "input.readMessage(value);\n"); + } + + printer->Print(variables_, + "add$capitalized_name$(value);\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (params_.java_use_vector()) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " output.write$group_or_message$($number$, get$capitalized_name$(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for ($type$ element : get$capitalized_name$List()) {\n" + " output.write$group_or_message$($number$, element);\n" + "}\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + if (params_.java_use_vector()) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .compute$group_or_message$Size($number$, get$capitalized_name$(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for ($type$ element : get$capitalized_name$List()) {\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .compute$group_or_message$Size($number$, element);\n" + "}\n"); + } +} + +string RepeatedMessageFieldGenerator::GetBoxedType() const { + return ClassName(params_, descriptor_->message_type()); +} + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message_field.h b/src/google/protobuf/compiler/javamicro/javamicro_message_field.h new file mode 100644 index 0000000..a32aa4e --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_message_field.h @@ -0,0 +1,95 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/javamicro/javamicro_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +class MessageFieldGenerator : public FieldGenerator { + public: + explicit MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params); + ~MessageFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); +}; + +class RepeatedMessageFieldGenerator : public FieldGenerator { + public: + explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + const Params& params); + ~RepeatedMessageFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_params.h b/src/google/protobuf/compiler/javamicro/javamicro_params.h new file mode 100644 index 0000000..a4a72b7 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_params.h @@ -0,0 +1,143 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2010 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: wink@google.com (Wink Saville) + +#ifndef PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_ +#define PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_ + +#include <map> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +enum eOptimization { JAVAMICRO_OPT_SPEED, JAVAMICRO_OPT_SPACE, JAVAMICRO_OPT_DEFAULT = JAVAMICRO_OPT_SPACE }; + +// Parameters for used by the generators +class Params { + public: + typedef map<string, string> NameMap; + private: + string empty_; + string base_name_; + eOptimization optimization_; + bool java_multiple_files_; + bool java_use_vector_; + NameMap java_packages_; + NameMap java_outer_classnames_; + + public: + Params(const string & base_name) : + empty_(""), + base_name_(base_name), + optimization_(JAVAMICRO_OPT_DEFAULT), + java_multiple_files_(false), + java_use_vector_(false) { + } + + const string& base_name() const { + return base_name_; + } + + bool has_java_package(const string& file_name) const { + return java_packages_.find(file_name) + != java_packages_.end(); + } + void set_java_package(const string& file_name, + const string& java_package) { + java_packages_[file_name] = java_package; + } + const string& java_package(const string& file_name) const { + NameMap::const_iterator itr; + + itr = java_packages_.find(file_name); + if (itr == java_packages_.end()) { + return empty_; + } else { + return itr->second; + } + } + const NameMap& java_packages() { + return java_packages_; + } + + bool has_java_outer_classname(const string& file_name) const { + return java_outer_classnames_.find(file_name) + != java_outer_classnames_.end(); + } + void set_java_outer_classname(const string& file_name, + const string& java_outer_classname) { + java_outer_classnames_[file_name] = java_outer_classname; + } + const string& java_outer_classname(const string& file_name) const { + NameMap::const_iterator itr; + + itr = java_outer_classnames_.find(file_name); + if (itr == java_outer_classnames_.end()) { + return empty_; + } else { + return itr->second; + } + } + const NameMap& java_outer_classnames() { + return java_outer_classnames_; + } + + void set_optimization(eOptimization optimization) { + optimization_ = optimization; + } + eOptimization optimization() const { + return optimization_; + } + + void set_java_multiple_files(bool value) { + java_multiple_files_ = value; + } + bool java_multiple_files() const { + return java_multiple_files_; + } + + void set_java_use_vector(bool value) { + java_use_vector_ = value; + } + bool java_use_vector() const { + return java_use_vector_; + } + +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_ diff --git a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc new file mode 100644 index 0000000..d6daa44 --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc @@ -0,0 +1,660 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/javamicro/javamicro_primitive_field.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +const char* PrimitiveTypeName(JavaType type) { + switch (type) { + case JAVATYPE_INT : return "int"; + case JAVATYPE_LONG : return "long"; + case JAVATYPE_FLOAT : return "float"; + case JAVATYPE_DOUBLE : return "double"; + case JAVATYPE_BOOLEAN: return "boolean"; + case JAVATYPE_STRING : return "java.lang.String"; + case JAVATYPE_BYTES : return "com.google.protobuf.micro.ByteStringMicro"; + case JAVATYPE_ENUM : return NULL; + case JAVATYPE_MESSAGE: return NULL; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +bool IsReferenceType(JavaType type) { + switch (type) { + case JAVATYPE_INT : return false; + case JAVATYPE_LONG : return false; + case JAVATYPE_FLOAT : return false; + case JAVATYPE_DOUBLE : return false; + case JAVATYPE_BOOLEAN: return false; + case JAVATYPE_STRING : return true; + case JAVATYPE_BYTES : return true; + case JAVATYPE_ENUM : return false; + case JAVATYPE_MESSAGE: return true; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +const char* GetCapitalizedType(const FieldDescriptor* field) { + switch (field->type()) { + case FieldDescriptor::TYPE_INT32 : return "Int32" ; + case FieldDescriptor::TYPE_UINT32 : return "UInt32" ; + case FieldDescriptor::TYPE_SINT32 : return "SInt32" ; + case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ; + case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; + case FieldDescriptor::TYPE_INT64 : return "Int64" ; + case FieldDescriptor::TYPE_UINT64 : return "UInt64" ; + case FieldDescriptor::TYPE_SINT64 : return "SInt64" ; + case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ; + case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; + case FieldDescriptor::TYPE_FLOAT : return "Float" ; + case FieldDescriptor::TYPE_DOUBLE : return "Double" ; + case FieldDescriptor::TYPE_BOOL : return "Bool" ; + case FieldDescriptor::TYPE_STRING : return "String" ; + case FieldDescriptor::TYPE_BYTES : return "Bytes" ; + case FieldDescriptor::TYPE_ENUM : return "Enum" ; + case FieldDescriptor::TYPE_GROUP : return "Group" ; + case FieldDescriptor::TYPE_MESSAGE : return "Message" ; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +// For encodings with fixed sizes, returns that size in bytes. Otherwise +// returns -1. +int FixedSize(FieldDescriptor::Type type) { + switch (type) { + case FieldDescriptor::TYPE_INT32 : return -1; + case FieldDescriptor::TYPE_INT64 : return -1; + case FieldDescriptor::TYPE_UINT32 : return -1; + case FieldDescriptor::TYPE_UINT64 : return -1; + case FieldDescriptor::TYPE_SINT32 : return -1; + case FieldDescriptor::TYPE_SINT64 : return -1; + case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size; + case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size; + case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size; + case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size; + case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize; + case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize; + + case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize; + case FieldDescriptor::TYPE_ENUM : return -1; + + case FieldDescriptor::TYPE_STRING : return -1; + case FieldDescriptor::TYPE_BYTES : return -1; + case FieldDescriptor::TYPE_GROUP : return -1; + case FieldDescriptor::TYPE_MESSAGE : return -1; + + // No default because we want the compiler to complain if any new + // types are added. + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; +} + +// Return true if the type is a that has variable length +// for instance String's. +bool IsVariableLenType(JavaType type) { + switch (type) { + case JAVATYPE_INT : return false; + case JAVATYPE_LONG : return false; + case JAVATYPE_FLOAT : return false; + case JAVATYPE_DOUBLE : return false; + case JAVATYPE_BOOLEAN: return false; + case JAVATYPE_STRING : return true; + case JAVATYPE_BYTES : return true; + case JAVATYPE_ENUM : return false; + case JAVATYPE_MESSAGE: return true; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +bool IsStringUtf8Handling(const FieldDescriptor* descriptor, + const Params params) { + return ((params.optimization() == JAVAMICRO_OPT_SPEED) + && (GetJavaType(descriptor) == JAVATYPE_STRING)); +} + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params, + map<string, string>* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + if (IsStringUtf8Handling(descriptor, params)) { + (*variables)["type"] = "com.google.protobuf.micro.StringUtf8Micro"; + string defaultValue = DefaultValue(params, descriptor); + if (defaultValue == "\"\"") { + (*variables)["default"] = + "com.google.protobuf.micro.StringUtf8Micro.EMPTY"; + } else { + (*variables)["default"] = "new com.google.protobuf.micro.StringUtf8Micro(" + + defaultValue + ")"; + } + } else { + (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); + (*variables)["default"] = DefaultValue(params, descriptor); + } + (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); + (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); + (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + WireFormat::TagSize(descriptor->number(), descriptor->type())); + if (IsReferenceType(GetJavaType(descriptor))) { + (*variables)["null_check"] = + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n"; + } else { + (*variables)["null_check"] = ""; + } + int fixed_size = FixedSize(descriptor->type()); + if (fixed_size != -1) { + (*variables)["fixed_size"] = SimpleItoa(fixed_size); + } + (*variables)["message_name"] = descriptor->containing_type()->name(); +} +} // namespace + +// =================================================================== + +PrimitiveFieldGenerator:: +PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params) + : FieldGenerator(params), descriptor_(descriptor) { + SetPrimitiveVariables(descriptor, params, &variables_); +} + +PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} + +void PrimitiveFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private boolean has$capitalized_name$;\n" + "private $type$ $name$_ = $default$;\n" + "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"); + if (IsStringUtf8Handling(descriptor_, params_)) { + printer->Print(variables_, + "public String get$capitalized_name$() { return $name$_.getString(); }\n" + "public $type$ get$capitalized_name$StringUtf8() { return $name$_; }\n" + "public $message_name$ set$capitalized_name$(String value) {\n" + " has$capitalized_name$ = true;\n" + " if ($name$_ == $default$) {\n" + " $name$_ = new $type$(value);\n" + " } else {\n" + " $name$_.setString(value);\n" + " }\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " has$capitalized_name$ = false;\n" + " $name$_ = $default$;\n" + " return this;\n" + "}\n"); + } else { + printer->Print(variables_, + "public $type$ get$capitalized_name$() { return $name$_; }\n"); + if (IsVariableLenType(GetJavaType(descriptor_))) { + printer->Print(variables_, + "public $message_name$ set$capitalized_name$($type$ value) {\n" + " has$capitalized_name$ = true;\n" + " $name$_ = value;\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " has$capitalized_name$ = false;\n" + " $name$_ = $default$;\n" + " return this;\n" + "}\n"); + } else { + printer->Print(variables_, + "public $message_name$ set$capitalized_name$($type$ value) {\n" + " has$capitalized_name$ = true;\n" + " $name$_ = value;\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " has$capitalized_name$ = false;\n" + " $name$_ = $default$;\n" + " return this;\n" + "}\n"); + } + } +} + +void PrimitiveFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void PrimitiveFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "set$capitalized_name$(input.read$capitalized_type$());\n"); +} + +void PrimitiveFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (IsStringUtf8Handling(descriptor_, params_)) { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " output.writeStringUtf8($number$, get$capitalized_name$StringUtf8());\n" + "}\n"); + } else { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " output.write$capitalized_type$($number$, get$capitalized_name$());\n" + "}\n"); + } +} + +void PrimitiveFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + if (IsStringUtf8Handling(descriptor_, params_)) { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .computeStringUtf8Size($number$, get$capitalized_name$StringUtf8());\n" + "}\n"); + } else { + printer->Print(variables_, + "if (has$capitalized_name$()) {\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .compute$capitalized_type$Size($number$, get$capitalized_name$());\n" + "}\n"); + } +} + +string PrimitiveFieldGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +// =================================================================== + +RepeatedPrimitiveFieldGenerator:: +RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params) + : FieldGenerator(params), descriptor_(descriptor) { + SetPrimitiveVariables(descriptor, params, &variables_); + if (descriptor_->options().packed()) { + GOOGLE_LOG(FATAL) << "MicroRuntime does not support packed"; + } +} + +RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} + +void RepeatedPrimitiveFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + if (IsStringUtf8Handling(descriptor_, params_)) { + if (params_.java_use_vector()) { + printer->Print(variables_, + "private java.util.Vector $name$_ = new java.util.Vector();\n" + "public java.util.Vector get$capitalized_name$List() {\n" + " return $name$_;\n" + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public String get$capitalized_name$(int index) {\n" + " return (($type$)$name$_.elementAt(index)).getString();\n" + "}\n" + "public $type$ get$capitalized_name$StringUtf8(int index) {\n" + " return ($type$)$name$_.elementAt(index);\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, String value) {\n" + "$null_check$" + " $name$_.setElementAt(new $type$(value), index);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$(String value) {\n" + "$null_check$" + " $name$_.addElement(new $type$(value));\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_.removeAllElements();\n" + " return this;\n" + "}\n"); + } else { + printer->Print(variables_, + "private java.util.List<$type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + "public java.util.List<$type$> get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public String get$capitalized_name$(int index) {\n" + " return $name$_.get(index).getString();\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, String value) {\n" + "$null_check$" + " $name$_.set(index, new $type$(value));\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$(String value) {\n" + "$null_check$" + " if ($name$_.isEmpty()) {\n" + " $name$_ = new java.util.ArrayList<$type$>();\n" + " }\n" + " $name$_.add(new $type$(value));\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_ = java.util.Collections.emptyList();\n" + " return this;\n" + "}\n"); + } + } else if (params_.java_use_vector()) { + if (IsReferenceType(GetJavaType(descriptor_))) { + printer->Print(variables_, + "private java.util.Vector $name$_ = new java.util.Vector();\n" + "public java.util.Vector get$capitalized_name$List() {\n" + " return $name$_;\n" + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public $type$ get$capitalized_name$(int index) {\n" + " return ($type$) $name$_.elementAt(index);\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" + "$null_check$" + " $name$_.setElementAt(value, index);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$($type$ value) {\n" + "$null_check$" + " $name$_.addElement(value);\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_.removeAllElements();\n" + " return this;\n" + "}\n"); + } else { + printer->Print(variables_, + "private java.util.Vector $name$_ = new java.util.Vector();\n" + "public java.util.Vector get$capitalized_name$List() {\n" + " return $name$_;\n" + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public $type$ get$capitalized_name$(int index) {\n" + " return (($boxed_type$)$name$_.elementAt(index)).$type$Value();\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" + "$null_check$" + " $name$_.setElementAt(new $boxed_type$(value), index);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$($type$ value) {\n" + "$null_check$" + " $name$_.addElement(new $boxed_type$(value));\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_.removeAllElements();\n" + " return this;\n" + "}\n"); + } + } else { + printer->Print(variables_, + "private java.util.List<$boxed_type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n" + "public int get$capitalized_name$Count() { return $name$_.size(); }\n" + "public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n" + "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" + "$null_check$" + " $name$_.set(index, value);\n" + " return this;\n" + "}\n" + "public $message_name$ add$capitalized_name$($type$ value) {\n" + "$null_check$" + " if ($name$_.isEmpty()) {\n" + " $name$_ = new java.util.ArrayList<$boxed_type$>();\n" + " }\n" + " $name$_.add(value);\n" + " return this;\n" + "}\n" + "public $message_name$ clear$capitalized_name$() {\n" + " $name$_ = java.util.Collections.emptyList();\n" + " return this;\n" + "}\n"); + } + if (descriptor_->options().packed()) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize;\n"); + } +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + if (params_.java_use_vector()) { + printer->Print(variables_, + "if (other.$name$_.size() != 0) {\n" + " for (int i = 0; i < other.$name$_.size(); i++)) {\n" + " result.$name$_.addElement(other.$name$_.elementAt(i));\n" + " }\n" + "}\n"); + } else { + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if (result.$name$_.isEmpty()) {\n" + " result.$name$_ = new java.util.ArrayList<$type$>();\n" + " }\n" + " result.$name$_.addAll(other.$name$_);\n" + "}\n"); + } +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " add$capitalized_name$(input.read$capitalized_type$());\n" + "}\n" + "input.popLimit(limit);\n"); + } else { + printer->Print(variables_, + "add$capitalized_name$(input.read$capitalized_type$());\n"); + } +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n"); + if (params_.java_use_vector()) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " output.write$capitalized_type$NoTag(get$capitalized_name$(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for ($type$ element : get$capitalized_name$List()) {\n" + " output.write$capitalized_type$NoTag(element);\n" + "}\n"); + } + } else { + if (params_.java_use_vector()) { + if (IsStringUtf8Handling(descriptor_, params_)) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " output.writeStringUtf8($number$, get$capitalized_name$StringUtf8(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " output.write$capitalized_type$($number$, get$capitalized_name$(i));\n" + "}\n"); + } + } else { + if (IsStringUtf8Handling(descriptor_, params_)) { + printer->Print(variables_, + "for ($type$ element : get$capitalized_name$List()) {\n" + " output.writeStringUtf8($number$, element);\n" + "}\n"); + } else { + printer->Print(variables_, + "for ($type$ element : get$capitalized_name$List()) {\n" + " output.write$capitalized_type$($number$, element);\n" + "}\n"); + } + } + } +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + if (FixedSize(descriptor_->type()) == -1) { + if (params_.java_use_vector()) { + printer->Print(variables_, + "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" + " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"); + if (IsStringUtf8Handling(descriptor_, params_)) { + printer->Print(variables_, + " .computeStringUtf8SizeNoTag(get$capitalized_name$StringUtf8(i));\n" + "}\n"); + } else { + printer->Print(variables_, + " .compute$capitalized_type$SizeNoTag(($type$)get$capitalized_name$(i));\n" + "}\n"); + } + } else { + printer->Print(variables_, + "for ($type$ element : get$capitalized_name$List()) {\n" + " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"); + if (IsStringUtf8Handling(descriptor_, params_)) { + printer->Print(variables_, + " .computeStringUtf8SizeNoTag(element);\n" + "}\n"); + } else { + printer->Print(variables_, + " .compute$capitalized_type$SizeNoTag(element);\n" + "}\n"); + } + } + } else { + printer->Print(variables_, + "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n"); + } + + printer->Print( + "size += dataSize;\n"); + + if (descriptor_->options().packed()) { + if (params_.java_use_vector()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() != 0) {\n"); + } else { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {\n"); + } + printer->Print(variables_, + " size += $tag_size$;\n" + " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" + " .computeInt32SizeNoTag(dataSize);\n" + "}\n"); + } else { + printer->Print(variables_, + "size += $tag_size$ * get$capitalized_name$List().size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +string RepeatedPrimitiveFieldGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h new file mode 100644 index 0000000..88d8eec --- /dev/null +++ b/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h @@ -0,0 +1,94 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/javamicro/javamicro_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace javamicro { + +class PrimitiveFieldGenerator : public FieldGenerator { + public: + explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params ¶ms); + ~PrimitiveFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); +}; + +class RepeatedPrimitiveFieldGenerator : public FieldGenerator { + public: + explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params); + ~RepeatedPrimitiveFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + void GenerateMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); +}; + +} // namespace javamicro +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__ diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index d9b0c3f..813a011 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -34,6 +34,7 @@ #include <google/protobuf/compiler/cpp/cpp_generator.h> #include <google/protobuf/compiler/python/python_generator.h> #include <google/protobuf/compiler/java/java_generator.h> +#include <google/protobuf/compiler/javamicro/javamicro_generator.h> int main(int argc, char* argv[]) { @@ -57,5 +58,10 @@ int main(int argc, char* argv[]) { cli.RegisterGenerator("--python_out", &py_generator, "Generate Python source file."); + // Proto2 JavaMicro + google::protobuf::compiler::javamicro::JavaMicroGenerator javamicro_generator; + cli.RegisterGenerator("--javamicro_out", &javamicro_generator, + "Generate Java source file micro runtime."); + return cli.Run(argc, argv); } diff --git a/src/google/protobuf/unittest_import_micro.proto b/src/google/protobuf/unittest_import_micro.proto new file mode 100644 index 0000000..adac807 --- /dev/null +++ b/src/google/protobuf/unittest_import_micro.proto @@ -0,0 +1,49 @@ +// 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) +// +// This is like unittest_import.proto but with optimize_for = MICRO_RUNTIME. + +package protobuf_unittest_import; + +// java_package and java_outer_classname are specified on the command line. +//option java_package = "com.google.protobuf.micro"; +//option java_outer_classname = "UnittestImportMicro"; + +message ImportMessageMicro { + optional int32 d = 1; +} + +enum ImportEnumMicro { + IMPORT_MICRO_FOO = 7; + IMPORT_MICRO_BAR = 8; + IMPORT_MICRO_BAZ = 9; +} diff --git a/src/google/protobuf/unittest_micro.proto b/src/google/protobuf/unittest_micro.proto new file mode 100644 index 0000000..3d7fcd2 --- /dev/null +++ b/src/google/protobuf/unittest_micro.proto @@ -0,0 +1,162 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: wink@google.com (Wink Saville) + +package protobuf_unittest; + +import "google/protobuf/unittest_import_micro.proto"; + +option java_package = "com.google.protobuf.micro"; +option java_outer_classname = "MicroOuterClass"; + +// Same as TestAllTypes but with the micro runtime. +message TestAllTypesMicro { + + message NestedMessage { + optional int32 bb = 1; + } + + enum NestedEnum { + FOO = 1; + BAR = 2; + BAZ = 3; + } + + // Singular + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + + optional group OptionalGroup = 16 { + optional int32 a = 17; + } + + optional NestedMessage optional_nested_message = 18; + optional ForeignMessageMicro optional_foreign_message = 19; + optional protobuf_unittest_import.ImportMessageMicro + optional_import_message = 20; + + optional NestedEnum optional_nested_enum = 21; + optional ForeignEnumMicro optional_foreign_enum = 22; + optional protobuf_unittest_import.ImportEnumMicro optional_import_enum = 23; + + optional string optional_string_piece = 24 [ctype=STRING_PIECE]; + optional string optional_cord = 25 [ctype=CORD]; + + // Repeated + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + repeated group RepeatedGroup = 46 { + optional int32 a = 47; + } + + repeated NestedMessage repeated_nested_message = 48; + repeated ForeignMessageMicro repeated_foreign_message = 49; + repeated protobuf_unittest_import.ImportMessageMicro + repeated_import_message = 50; + + repeated NestedEnum repeated_nested_enum = 51; + repeated ForeignEnumMicro repeated_foreign_enum = 52; + repeated protobuf_unittest_import.ImportEnumMicro repeated_import_enum = 53; + + repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; + repeated string repeated_cord = 55 [ctype=CORD]; + + // Singular with defaults + optional int32 default_int32 = 61 [default = 41 ]; + optional int64 default_int64 = 62 [default = 42 ]; + optional uint32 default_uint32 = 63 [default = 43 ]; + optional uint64 default_uint64 = 64 [default = 44 ]; + optional sint32 default_sint32 = 65 [default = -45 ]; + optional sint64 default_sint64 = 66 [default = 46 ]; + optional fixed32 default_fixed32 = 67 [default = 47 ]; + optional fixed64 default_fixed64 = 68 [default = 48 ]; + optional sfixed32 default_sfixed32 = 69 [default = 49 ]; + optional sfixed64 default_sfixed64 = 70 [default = -50 ]; + optional float default_float = 71 [default = 51.5 ]; + optional double default_double = 72 [default = 52e3 ]; + optional bool default_bool = 73 [default = true ]; + optional string default_string = 74 [default = "hello"]; + optional bytes default_bytes = 75 [default = "world"]; + + optional NestedEnum default_nested_enum = 81 [default = BAR]; + optional ForeignEnumMicro default_foreign_enum = 82 + [default = FOREIGN_MICRO_BAR]; + optional protobuf_unittest_import.ImportEnumMicro + default_import_enum = 83 [default = IMPORT_MICRO_BAR]; + + optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; + optional string default_cord = 85 [ctype=CORD,default="123"]; + + required int32 id = 86; +} + +message ForeignMessageMicro { + optional int32 c = 1; +} + +enum ForeignEnumMicro { + FOREIGN_MICRO_FOO = 4; + FOREIGN_MICRO_BAR = 5; + FOREIGN_MICRO_BAZ = 6; +} + +// Test that deprecated fields work. We only verify that they compile (at one +// point this failed). +message TestDeprecatedMicro { + optional int32 deprecated_field = 1 [deprecated = true]; +} diff --git a/src/google/protobuf/unittest_recursive_micro.proto b/src/google/protobuf/unittest_recursive_micro.proto new file mode 100644 index 0000000..a256852 --- /dev/null +++ b/src/google/protobuf/unittest_recursive_micro.proto @@ -0,0 +1,47 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: wink@google.com (Wink Saville) +// + +package protobuf_unittest_import; + +option java_package = "com.google.protobuf.micro"; + +message RecursiveMessageMicro { + message NestedMessage { + optional RecursiveMessageMicro a = 1; + } + + required int32 id = 1; + optional NestedMessage nested_message = 2; + optional RecursiveMessageMicro optional_recursive_message_micro = 3; + repeated RecursiveMessageMicro repeated_recursive_message_micro = 4; +} diff --git a/src/google/protobuf/unittest_simple_micro.proto b/src/google/protobuf/unittest_simple_micro.proto new file mode 100644 index 0000000..057bf3d --- /dev/null +++ b/src/google/protobuf/unittest_simple_micro.proto @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: wink@google.com (Wink Saville) +// + +package protobuf_unittest_import; + +option java_package = "com.google.protobuf.micro"; + +message SimpleMessageMicro { + message NestedMessage { + optional int32 bb = 1; + } + + enum NestedEnum { + FOO = 1; + BAR = 2; + BAZ = 3; + } + + optional int32 d = 1 [default = 123]; + optional NestedMessage nested_msg = 2; + optional NestedEnum default_nested_enum = 3 [default = BAZ]; +} diff --git a/src/google/protobuf/unittest_stringutf8_micro.proto b/src/google/protobuf/unittest_stringutf8_micro.proto new file mode 100644 index 0000000..e4bbe3d --- /dev/null +++ b/src/google/protobuf/unittest_stringutf8_micro.proto @@ -0,0 +1,41 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: wink@google.com (Wink Saville) +// + +package protobuf_unittest_import; + +option java_package = "com.google.protobuf.micro"; + +message StringUtf8 { + optional string id = 1; + repeated string rs = 2; +} |