From 45eb28b588a3b4ef5e54abf92b1f2b7eafb2cbf8 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Mon, 14 May 2018 16:06:22 -0700 Subject: [PATCH 01/28] Update version number to 3.6.0 --- Protobuf.podspec | 2 +- configure.ac | 2 +- csharp/Google.Protobuf.Tools.nuspec | 2 +- csharp/src/Google.Protobuf/Google.Protobuf.csproj | 2 +- java/core/pom.xml | 2 +- java/pom.xml | 2 +- java/util/pom.xml | 2 +- js/package.json | 2 +- protoc-artifacts/pom.xml | 2 +- python/google/protobuf/__init__.py | 2 +- ruby/google-protobuf.gemspec | 2 +- src/Makefile.am | 6 +++--- src/google/protobuf/any.pb.h | 4 ++-- src/google/protobuf/api.pb.h | 4 ++-- src/google/protobuf/compiler/plugin.pb.h | 4 ++-- src/google/protobuf/descriptor.pb.h | 4 ++-- src/google/protobuf/duration.pb.h | 4 ++-- src/google/protobuf/empty.pb.h | 4 ++-- src/google/protobuf/field_mask.pb.h | 4 ++-- src/google/protobuf/source_context.pb.h | 4 ++-- src/google/protobuf/struct.pb.h | 4 ++-- src/google/protobuf/stubs/common.h | 10 +++++----- src/google/protobuf/timestamp.pb.h | 4 ++-- src/google/protobuf/type.pb.h | 4 ++-- src/google/protobuf/wrappers.pb.h | 4 ++-- 25 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Protobuf.podspec b/Protobuf.podspec index 24498a27ed..b5bb673ee1 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -5,7 +5,7 @@ # dependent projects use the :git notation to refer to the library. Pod::Spec.new do |s| s.name = 'Protobuf' - s.version = '3.5.2' + s.version = '3.6.0' s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.' s.homepage = 'https://github.com/google/protobuf' s.license = '3-Clause BSD License' diff --git a/configure.ac b/configure.ac index 6e9ce1f5af..08f98d3b68 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.59) # In the SVN trunk, the version should always be the next anticipated release # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # the size of one file name in the dist tarfile over the 99-char limit.) -AC_INIT([Protocol Buffers],[3.5.2],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[3.6.0],[protobuf@googlegroups.com],[protobuf]) AM_MAINTAINER_MODE([enable]) diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 4294949f66..ae8cdd74ae 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -5,7 +5,7 @@ Google Protocol Buffers tools Tools for Protocol Buffers - Google's data interchange format. See project site for more info. - 3.5.2 + 3.6.0 Google Inc. protobuf-packages https://github.com/google/protobuf/blob/master/LICENSE diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index 6e4e1e2bce..d19531aac7 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -4,7 +4,7 @@ C# runtime library for Protocol Buffers - Google's data interchange format. Copyright 2015, Google Inc. Google Protocol Buffers - 3.5.2 + 3.6.0 Google Inc. netstandard1.0;net45 true diff --git a/java/core/pom.xml b/java/core/pom.xml index 8139241b3b..b4edcbc7d2 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -6,7 +6,7 @@ com.google.protobuf protobuf-parent - 3.5.2 + 3.6.0 protobuf-java diff --git a/java/pom.xml b/java/pom.xml index f2284918f5..35d653b44e 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ com.google.protobuf protobuf-parent - 3.5.2 + 3.6.0 pom Protocol Buffers [Parent] diff --git a/java/util/pom.xml b/java/util/pom.xml index 4e55df0d29..8ea4a40dd1 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -6,7 +6,7 @@ com.google.protobuf protobuf-parent - 3.5.2 + 3.6.0 protobuf-java-util diff --git a/js/package.json b/js/package.json index 39d99f9370..325f2dcc58 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "google-protobuf", - "version": "3.5.2", + "version": "3.6.0", "description": "Protocol Buffers for JavaScript", "main": "google-protobuf.js", "files": [ diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml index 298730a6e9..667a021524 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -10,7 +10,7 @@ com.google.protobuf protoc - 3.5.2 + 3.6.0 pom Protobuf Compiler diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index d43607271c..58a3f040cb 100755 --- a/python/google/protobuf/__init__.py +++ b/python/google/protobuf/__init__.py @@ -30,7 +30,7 @@ # Copyright 2007 Google Inc. All Rights Reserved. -__version__ = '3.5.2' +__version__ = '3.6.0' if __name__ != '__main__': try: diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index c09a7f2451..cc7625d46e 100644 --- a/ruby/google-protobuf.gemspec +++ b/ruby/google-protobuf.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "google-protobuf" - s.version = "3.5.2" + s.version = "3.6.0" s.licenses = ["BSD-3-Clause"] s.summary = "Protocol Buffers" s.description = "Protocol Buffers are Google's data interchange format." diff --git a/src/Makefile.am b/src/Makefile.am index 7310210ead..fb247300d4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -166,7 +166,7 @@ nobase_include_HEADERS = \ lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_lite_la_LDFLAGS = -version-info 15:1:0 -export-dynamic -no-undefined +libprotobuf_lite_la_LDFLAGS = -version-info 16:0:0 -export-dynamic -no-undefined if HAVE_LD_VERSION_SCRIPT libprotobuf_lite_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf-lite.map EXTRA_libprotobuf_lite_la_DEPENDENCIES = libprotobuf-lite.map @@ -212,7 +212,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/io/zero_copy_stream_impl_lite.cc libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 15:1:0 -export-dynamic -no-undefined +libprotobuf_la_LDFLAGS = -version-info 16:0:0 -export-dynamic -no-undefined if HAVE_LD_VERSION_SCRIPT libprotobuf_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf.map EXTRA_libprotobuf_la_DEPENDENCIES = libprotobuf.map @@ -303,7 +303,7 @@ libprotobuf_la_SOURCES = \ nodist_libprotobuf_la_SOURCES = $(nodist_libprotobuf_lite_la_SOURCES) libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la -libprotoc_la_LDFLAGS = -version-info 15:1:0 -export-dynamic -no-undefined +libprotoc_la_LDFLAGS = -version-info 16:0:0 -export-dynamic -no-undefined if HAVE_LD_VERSION_SCRIPT libprotoc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotoc.map EXTRA_libprotoc_la_DEPENDENCIES = libprotoc.map diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index bc53799957..8a4c7f97e6 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 5a720cce8c..0f90f411c4 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 5ad6b4d322..d5b70a8810 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 5e7a05d5e4..7a8617a200 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 3d0889d1b6..751edbefc1 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 53857e5fe9..c3da4fa8b7 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index 144b41fae0..7550f7a97f 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 16ed21ca61..eee1b73f44 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 75665ff264..b2263435ae 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index c336383d42..5d320764d8 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -101,27 +101,27 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 3005001 +#define GOOGLE_PROTOBUF_VERSION 3006000 // A suffix string for alpha, beta or rc releases. Empty for stable releases. #define GOOGLE_PROTOBUF_VERSION_SUFFIX "" // The minimum library version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3005000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3006000 // The minimum header version which works with the current version of // the library. This constant should only be used by protoc's C++ code // generator. -static const int kMinHeaderVersionForLibrary = 3005000; +static const int kMinHeaderVersionForLibrary = 3006000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3005000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3006000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 3005000; +static const int kMinHeaderVersionForProtoc = 3006000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index f73e75b3ee..daea80f6b7 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 69af6c2e91..cbd0cdccce 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 9f51a0626c..b00d4ea91a 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3005000 +#if GOOGLE_PROTOBUF_VERSION < 3006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. From daf039b8cd2f29cbc129273e11e269afd667ee06 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 24 May 2018 11:55:42 -0700 Subject: [PATCH 02/28] Make sure to delete temporary maps used by FileDescriptorTables I ran the tcmalloc heap checker in draconian mode, and it reported some heap allocations that were still reachable when protobuf-test exited. To fix that, I updated FileDescriptorTables to make sure its temporary heap-allocated maps are deleted when it is destroyed. --- src/google/protobuf/descriptor.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index d466dd8b4e..83eae519ef 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -775,10 +775,10 @@ class FileDescriptorTables { SymbolsByParentMap symbols_by_parent_; mutable FieldsByNameMap fields_by_lowercase_name_; - mutable FieldsByNameMap* fields_by_lowercase_name_tmp_; + std::unique_ptr fields_by_lowercase_name_tmp_; mutable GoogleOnceDynamic fields_by_lowercase_name_once_; mutable FieldsByNameMap fields_by_camelcase_name_; - mutable FieldsByNameMap* fields_by_camelcase_name_tmp_; + std::unique_ptr fields_by_camelcase_name_tmp_; mutable GoogleOnceDynamic fields_by_camelcase_name_once_; FieldsByNumberMap fields_by_number_; // Not including extensions. EnumValuesByNumberMap enum_values_by_number_; @@ -1146,10 +1146,8 @@ bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { void FileDescriptorTables::FinalizeTables() { // Clean up the temporary maps used by AddFieldByStylizedNames(). - delete fields_by_lowercase_name_tmp_; - fields_by_lowercase_name_tmp_ = NULL; - delete fields_by_camelcase_name_tmp_; - fields_by_camelcase_name_tmp_ = NULL; + fields_by_lowercase_name_tmp_ = nullptr; + fields_by_camelcase_name_tmp_ = nullptr; } void FileDescriptorTables::AddFieldByStylizedNames( @@ -1164,7 +1162,7 @@ void FileDescriptorTables::AddFieldByStylizedNames( // entries from fields_by_number_. PointerStringPair lowercase_key(parent, field->lowercase_name().c_str()); - if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_, lowercase_key, + if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_.get(), lowercase_key, field)) { InsertIfNotPresent( &fields_by_lowercase_name_, lowercase_key, @@ -1172,7 +1170,7 @@ void FileDescriptorTables::AddFieldByStylizedNames( } PointerStringPair camelcase_key(parent, field->camelcase_name().c_str()); - if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_, camelcase_key, + if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_.get(), camelcase_key, field)) { InsertIfNotPresent( &fields_by_camelcase_name_, camelcase_key, From d8483a92d7867af37afb8b439e4f64c915654c1f Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Mon, 14 May 2018 16:08:47 -0700 Subject: [PATCH 03/28] Adopt php_metadata_namespace in php code generator (#4622) * Adopt php_metadata_namespace in php code generator The php_metadata_namespace is corresponded to the relative directory of the metadata file. e.g., previously, the metadata file of foo.proto was GPBMetadata/Foo.php. If the php_metadata_namespace is "Metadata\\Bar", the metadata file will be Metadata/Bar/Foo.php. * Handle empty php_metadata_namespace --- .../proto/test_empty_php_namespace.proto | 1 + php/tests/proto/test_no_namespace.proto | 2 + php/tests/proto/test_php_namespace.proto | 1 + .../protobuf/compiler/php/php_generator.cc | 54 +++++++++++++------ 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/php/tests/proto/test_empty_php_namespace.proto b/php/tests/proto/test_empty_php_namespace.proto index 7b4bc74d14..1d02f76095 100644 --- a/php/tests/proto/test_empty_php_namespace.proto +++ b/php/tests/proto/test_empty_php_namespace.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package foo; option php_namespace = ""; +option php_metadata_namespace = ""; message TestEmptyNamespace { int32 a = 1; diff --git a/php/tests/proto/test_no_namespace.proto b/php/tests/proto/test_no_namespace.proto index 58f13d47bc..03f89270ed 100644 --- a/php/tests/proto/test_no_namespace.proto +++ b/php/tests/proto/test_no_namespace.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +option php_metadata_namespace = "\\"; + message NoNamespaceMessage { int32 a = 1; diff --git a/php/tests/proto/test_php_namespace.proto b/php/tests/proto/test_php_namespace.proto index 713187b9b0..bb57d6177d 100644 --- a/php/tests/proto/test_php_namespace.proto +++ b/php/tests/proto/test_php_namespace.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package foo; option php_namespace = "Php\\Test"; +option php_metadata_namespace = "Metadata\\Php\\Test"; message TestNamespace { int32 a = 1; diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 4e237fc78f..a37380e362 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -83,7 +83,7 @@ std::string PhpName(const std::string& full_name, bool is_descriptor); std::string DefaultForField(FieldDescriptor* field); std::string IntToString(int32 value); std::string FilenameToClassname(const string& filename); -std::string GeneratedMetadataFileName(const std::string& proto_file, +std::string GeneratedMetadataFileName(const FileDescriptor* file, bool is_descriptor); std::string LabelForField(FieldDescriptor* field); std::string TypeName(FieldDescriptor* field); @@ -268,11 +268,12 @@ std::string DefaultForField(const FieldDescriptor* field) { } } -std::string GeneratedMetadataFileName(const std::string& proto_file, +std::string GeneratedMetadataFileName(const FileDescriptor* file, bool is_descriptor) { + const string& proto_file = file->name(); int start_index = 0; int first_index = proto_file.find_first_of("/", start_index); - std::string result = "GPBMetadata/"; + std::string result = ""; if (proto_file == kEmptyFile) { return kEmptyMetadataFile; @@ -290,17 +291,36 @@ std::string GeneratedMetadataFileName(const std::string& proto_file, file_no_suffix = proto_file.substr(0, lastindex); } - while (first_index != string::npos) { - result += UnderscoresToCamelCase( - file_no_suffix.substr(start_index, first_index - start_index), true); - result += "/"; - start_index = first_index + 1; - first_index = file_no_suffix.find_first_of("/", start_index); + if (file->options().has_php_metadata_namespace()) { + const string& php_metadata_namespace = + file->options().php_metadata_namespace(); + if (php_metadata_namespace != "" && php_metadata_namespace != "\\") { + result += php_metadata_namespace; + std::replace(result.begin(), result.end(), '\\', '/'); + if (result.at(result.size() - 1) != '/') { + result += "/"; + } + } + } else { + result += "GPBMetadata/"; + while (first_index != string::npos) { + result += UnderscoresToCamelCase( + file_no_suffix.substr(start_index, first_index - start_index), true); + result += "/"; + start_index = first_index + 1; + first_index = file_no_suffix.find_first_of("/", start_index); + } } // Append file name. + int file_name_start = file_no_suffix.find_last_of("/"); + if (file_name_start == string::npos) { + file_name_start = 0; + } else { + file_name_start += 1; + } result += RenameEmpty(UnderscoresToCamelCase( - file_no_suffix.substr(start_index, first_index - start_index), true)); + file_no_suffix.substr(file_name_start, first_index - file_name_start), true)); return result += ".php"; } @@ -851,7 +871,7 @@ void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor, continue; } std::string dependency_filename = - GeneratedMetadataFileName(name, is_descriptor); + GeneratedMetadataFileName(file->dependency(i), is_descriptor); printer->Print( "\\^name^::initOnce();\n", "name", FilenameToClassname(dependency_filename)); @@ -945,7 +965,7 @@ std::string FilenameToClassname(const string& filename) { void GenerateMetadataFile(const FileDescriptor* file, bool is_descriptor, GeneratorContext* generator_context) { - std::string filename = GeneratedMetadataFileName(file->name(), is_descriptor); + std::string filename = GeneratedMetadataFileName(file, is_descriptor); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -955,11 +975,11 @@ void GenerateMetadataFile(const FileDescriptor* file, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - printer.Print( - "namespace ^name^;\n\n", - "name", fullname.substr(0, lastindex)); - if (lastindex != string::npos) { + printer.Print( + "namespace ^name^;\n\n", + "name", fullname.substr(0, lastindex)); + printer.Print( "class ^name^\n" "{\n", @@ -1094,7 +1114,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, Indent(&printer); std::string metadata_filename = - GeneratedMetadataFileName(file->name(), is_descriptor); + GeneratedMetadataFileName(file, is_descriptor); std::string metadata_fullname = FilenameToClassname(metadata_filename); printer.Print( "\\^fullname^::initOnce();\n" From 5289ee0c2139b691111037806f088e306a31ac70 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Thu, 17 May 2018 17:11:06 -0700 Subject: [PATCH 04/28] Adopt ruby_package in ruby generated code. (#4627) * Adopt ruby_package in ruby generated code. * Add test for ruby_package --- .gitignore | 1 + ruby/Rakefile | 5 +++++ ruby/tests/generated_code_test.rb | 2 ++ ruby/tests/test_ruby_package.proto | 7 +++++++ .../protobuf/compiler/ruby/ruby_generator.cc | 19 ++++++++++++++++--- 5 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 ruby/tests/test_ruby_package.proto diff --git a/.gitignore b/.gitignore index abd72fc940..d886259c60 100644 --- a/.gitignore +++ b/.gitignore @@ -174,6 +174,7 @@ js/testproto_libs2.js ruby/lib/ ruby/tests/generated_code_pb.rb ruby/tests/test_import_pb.rb +ruby/tests/test_ruby_package_pb.rb ruby/Gemfile.lock ruby/compatibility_tests/v3.0.0/protoc ruby/compatibility_tests/v3.0.0/tests/generated_code_pb.rb diff --git a/ruby/Rakefile b/ruby/Rakefile index ff09cebbb8..013bc99a40 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -87,6 +87,7 @@ end # Proto for tests. genproto_output << "tests/generated_code.rb" genproto_output << "tests/test_import.rb" +genproto_output << "tests/test_ruby_package.rb" file "tests/generated_code.rb" => "tests/generated_code.proto" do |file_task| sh "../src/protoc --ruby_out=. tests/generated_code.proto" end @@ -95,6 +96,10 @@ file "tests/test_import.rb" => "tests/test_import.proto" do |file_task| sh "../src/protoc --ruby_out=. tests/test_import.proto" end +file "tests/test_ruby_package.rb" => "tests/test_ruby_package.proto" do |file_task| + sh "../src/protoc --ruby_out=. tests/test_ruby_package.proto" +end + task :genproto => genproto_output task :clean do diff --git a/ruby/tests/generated_code_test.rb b/ruby/tests/generated_code_test.rb index b92b0462d1..431d681bb3 100644 --- a/ruby/tests/generated_code_test.rb +++ b/ruby/tests/generated_code_test.rb @@ -5,6 +5,7 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) require 'generated_code_pb' require 'test_import_pb' +require 'test_ruby_package_pb' require 'test/unit' class GeneratedCodeTest < Test::Unit::TestCase @@ -15,5 +16,6 @@ class GeneratedCodeTest < Test::Unit::TestCase # aspect of the extension (basic.rb is for that). m = A::B::C::TestMessage.new() m2 = FooBar::TestImportedMessage.new() + m3 = A::B::TestRubyPackageMessage.new() end end diff --git a/ruby/tests/test_ruby_package.proto b/ruby/tests/test_ruby_package.proto new file mode 100644 index 0000000000..b872562028 --- /dev/null +++ b/ruby/tests/test_ruby_package.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +package foo_bar; + +option ruby_package = "A.B"; + +message TestRubyPackageMessage {} diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index 02aa61d1b2..bd737c0278 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -337,9 +337,20 @@ void GenerateEnumAssignment( } int GeneratePackageModules( - std::string package_name, + const FileDescriptor* file, google::protobuf::io::Printer* printer) { int levels = 0; + bool need_change_to_module; + std::string package_name; + + if (file->options().has_ruby_package()) { + package_name = file->options().ruby_package(); + need_change_to_module = false; + } else { + package_name = file->package(); + need_change_to_module = true; + } + while (!package_name.empty()) { size_t dot_index = package_name.find("."); string component; @@ -350,7 +361,9 @@ int GeneratePackageModules( component = package_name.substr(0, dot_index); package_name = package_name.substr(dot_index + 1); } - component = PackageToModule(component); + if (need_change_to_module) { + component = PackageToModule(component); + } printer->Print( "module $name$\n", "name", component); @@ -462,7 +475,7 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, printer->Print( "end\n\n"); - int levels = GeneratePackageModules(file->package(), printer); + int levels = GeneratePackageModules(file, printer); for (int i = 0; i < file->message_type_count(); i++) { GenerateMessageAssignment("", file->message_type(i), printer); } From c19fcee48f064c6a49d865374c3adb37daa3f0dd Mon Sep 17 00:00:00 2001 From: Erik Benoist Date: Tue, 22 May 2018 10:14:04 -0500 Subject: [PATCH 05/28] Allows the json marshaller to be passed json marshal options (#4252) --- ruby/lib/google/protobuf.rb | 4 ++-- ruby/lib/google/protobuf/message_exts.rb | 4 ++-- ruby/tests/encode_decode_test.rb | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb index 9b8d8231e2..4a805e88cc 100644 --- a/ruby/lib/google/protobuf.rb +++ b/ruby/lib/google/protobuf.rb @@ -60,8 +60,8 @@ module Google msg.to_proto end - def self.encode_json(msg) - msg.to_json + def self.encode_json(msg, options = {}) + msg.to_json(options) end def self.decode(klass, proto) diff --git a/ruby/lib/google/protobuf/message_exts.rb b/ruby/lib/google/protobuf/message_exts.rb index e10266ba2f..f432f89fed 100644 --- a/ruby/lib/google/protobuf/message_exts.rb +++ b/ruby/lib/google/protobuf/message_exts.rb @@ -40,8 +40,8 @@ module Google module ClassMethods end - def to_json - self.class.encode_json(self) + def to_json(options = {}) + self.class.encode_json(self, options) end def to_proto diff --git a/ruby/tests/encode_decode_test.rb b/ruby/tests/encode_decode_test.rb index 09581ab07d..2bd9b98b5a 100644 --- a/ruby/tests/encode_decode_test.rb +++ b/ruby/tests/encode_decode_test.rb @@ -60,4 +60,28 @@ class EncodeDecodeTest < Test::Unit::TestCase to = A::B::C::TestMessage.encode(m.oneof_msg) assert_equal '', to end + + def test_encode_json + msg = A::B::C::TestMessage.new({ optional_int32: 22 }) + json = msg.to_json + + to = A::B::C::TestMessage.decode_json(json) + assert_equal to.optional_int32, 22 + + msg = A::B::C::TestMessage.new({ optional_int32: 22 }) + json = msg.to_json({ preserve_proto_fieldnames: true }) + + assert_match 'optional_int32', json + + to = A::B::C::TestMessage.decode_json(json) + assert_equal 22, to.optional_int32 + + msg = A::B::C::TestMessage.new({ optional_int32: 22 }) + json = A::B::C::TestMessage.encode_json( + msg, + { preserve_proto_fieldnames: true, emit_defaults: true } + ) + + assert_match 'optional_int32', json + end end From 7eba62465375b15a28d3f7bbd08f4f517b90b076 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Tue, 22 May 2018 09:53:03 -0700 Subject: [PATCH 06/28] Add missing ruby/tests/test_ruby_package.proto --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 48f2c03465..971e46ee75 100644 --- a/Makefile.am +++ b/Makefile.am @@ -904,6 +904,7 @@ ruby_EXTRA_DIST= \ ruby/tests/stress.rb \ ruby/tests/generated_code.proto \ ruby/tests/test_import.proto \ + ruby/tests/test_ruby_package.proto \ ruby/tests/generated_code_test.rb \ ruby/tests/well_known_types_test.rb \ ruby/travis-test.sh From c9b404d23bdf3dd8f1556b19a27dcba40565e3e4 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 2 May 2018 14:40:15 -0700 Subject: [PATCH 07/28] PHP array constructors for protobuf messages (#4530) * PHP array constructors for protobuf messages * removes Descriptor from error message * allows mergeFrom to accept an array * only use initWithDescriptor if instanceof MapEntry * adds doc comments * removes ability for constructors to take arrays for submessages * Revert "allows mergeFrom to accept an array" This reverts commit b7b72182d561634af12c5c5c56a7cda3b33241f9. * makes mergeFromArray protected and fixes mergeFrom whitespace * Separates merging from JSON and merging from PHP array * removes well-known types and json keys from array construction * Addresses PR review comments * cleans up tests * fixes exception messages --- .../Protobuf/Internal/DescriptorProto.php | 24 +- .../DescriptorProto_ExtensionRange.php | 15 +- .../DescriptorProto_ReservedRange.php | 16 +- .../Protobuf/Internal/EnumDescriptorProto.php | 22 +- .../EnumDescriptorProto_EnumReservedRange.php | 16 +- .../Google/Protobuf/Internal/EnumOptions.php | 22 +- .../Internal/EnumValueDescriptorProto.php | 15 +- .../Protobuf/Internal/EnumValueOptions.php | 19 +- .../Internal/ExtensionRangeOptions.php | 14 +- .../Internal/FieldDescriptorProto.php | 42 ++- .../Google/Protobuf/Internal/FieldOptions.php | 68 ++++- .../Protobuf/Internal/FileDescriptorProto.php | 37 ++- .../Protobuf/Internal/FileDescriptorSet.php | 13 +- .../Google/Protobuf/Internal/FileOptions.php | 87 +++++- .../Protobuf/Internal/GeneratedCodeInfo.php | 15 +- .../Internal/GeneratedCodeInfo_Annotation.php | 24 +- php/src/Google/Protobuf/Internal/Message.php | 248 +++++++++++------- .../Protobuf/Internal/MessageOptions.php | 58 +++- .../Internal/MethodDescriptorProto.php | 22 +- .../Protobuf/Internal/MethodOptions.php | 20 +- .../Internal/OneofDescriptorProto.php | 14 +- .../Google/Protobuf/Internal/OneofOptions.php | 14 +- .../Internal/ServiceDescriptorProto.php | 15 +- .../Protobuf/Internal/ServiceOptions.php | 19 +- .../Protobuf/Internal/SourceCodeInfo.php | 54 +++- .../Internal/SourceCodeInfo_Location.php | 79 +++++- .../Protobuf/Internal/UninterpretedOption.php | 21 +- .../Internal/UninterpretedOption_NamePart.php | 14 +- php/tests/generated_phpdoc_test.php | 8 + php/tests/php_implementation_test.php | 154 ++++++++++- .../protobuf/compiler/php/php_generator.cc | 54 +++- 31 files changed, 1082 insertions(+), 161 deletions(-) diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto.php b/php/src/Google/Protobuf/Internal/DescriptorProto.php index 1d6959b71d..4676269e46 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto.php @@ -71,9 +71,29 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message private $reserved_name; private $has_reserved_name = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * @type \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $field + * @type \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $extension + * @type \Google\Protobuf\Internal\DescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $nested_type + * @type \Google\Protobuf\Internal\EnumDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $enum_type + * @type \Google\Protobuf\Internal\DescriptorProto_ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $extension_range + * @type \Google\Protobuf\Internal\OneofDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $oneof_decl + * @type \Google\Protobuf\Internal\MessageOptions $options + * @type \Google\Protobuf\Internal\DescriptorProto_ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range + * @type string[]|\Google\Protobuf\Internal\RepeatedField $reserved_name + * Reserved field names, which may not be used by fields in the same message. + * A given name may only be reserved once. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php index 1d45599577..d926ee6e80 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php @@ -31,9 +31,20 @@ class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message private $options = null; private $has_options = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $start + * @type int $end + * @type \Google\Protobuf\Internal\ExtensionRangeOptions $options + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php index b1022d6154..302eaaa948 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php @@ -34,9 +34,21 @@ class DescriptorProto_ReservedRange extends \Google\Protobuf\Internal\Message private $end = 0; private $has_end = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $start + * Inclusive. + * @type int $end + * Exclusive. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php index 930f26ef6e..406bb5b50d 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php @@ -50,9 +50,27 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message private $reserved_name; private $has_reserved_name = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * @type \Google\Protobuf\Internal\EnumValueDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $value + * @type \Google\Protobuf\Internal\EnumOptions $options + * @type \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range + * Range of reserved numeric values. Reserved numeric values may not be used + * by enum values in the same enum declaration. Reserved ranges may not + * overlap. + * @type string[]|\Google\Protobuf\Internal\RepeatedField $reserved_name + * Reserved enum value names, which may not be reused. A given name may only + * be reserved once. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php index 6b2449faee..3d7b008eb8 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php @@ -36,9 +36,21 @@ class EnumDescriptorProto_EnumReservedRange extends \Google\Protobuf\Internal\Me private $end = 0; private $has_end = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $start + * Inclusive. + * @type int $end + * Inclusive. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/EnumOptions.php b/php/src/Google/Protobuf/Internal/EnumOptions.php index 3f598a41e7..3d74c81c21 100644 --- a/php/src/Google/Protobuf/Internal/EnumOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumOptions.php @@ -41,9 +41,27 @@ class EnumOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type bool $allow_alias + * Set this option to true to allow mapping different tag names to the same + * value. + * @type bool $deprecated + * Is this enum deprecated? + * Depending on the target platform, this can emit Deprecated annotations + * for the enum, or it will be completely ignored; in the very least, this + * is a formalization for deprecating enums. + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php index e363220fc1..50bda008e8 100644 --- a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php @@ -33,9 +33,20 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message private $options = null; private $has_options = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * @type int $number + * @type \Google\Protobuf\Internal\EnumValueOptions $options + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/EnumValueOptions.php b/php/src/Google/Protobuf/Internal/EnumValueOptions.php index db8de174d7..a267c6d5e2 100644 --- a/php/src/Google/Protobuf/Internal/EnumValueOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumValueOptions.php @@ -33,9 +33,24 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type bool $deprecated + * Is this enum value deprecated? + * Depending on the target platform, this can emit Deprecated annotations + * for the enum value, or it will be completely ignored; in the very least, + * this is a formalization for deprecating enum values. + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php index ee9e38bbd2..00fbebecaf 100644 --- a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php +++ b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php @@ -23,9 +23,19 @@ class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php index 10c2759330..e578197515 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php @@ -94,9 +94,47 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message private $options = null; private $has_options = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * @type int $number + * @type int $label + * @type int $type + * If type_name is set, this need not be set. If both this and type_name + * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + * @type string $type_name + * For message and enum types, this is the name of the type. If the name + * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + * rules are used to find the type (i.e. first the nested types within this + * message are searched, then within the parent, on up to the root + * namespace). + * @type string $extendee + * For extensions, this is the name of the type being extended. It is + * resolved in the same manner as type_name. + * @type string $default_value + * For numeric types, contains the original text representation of the value. + * For booleans, "true" or "false". + * For strings, contains the default text contents (not escaped in any way). + * For bytes, contains the C escaped value. All bytes >= 128 are escaped. + * TODO(kenton): Base-64 encode? + * @type int $oneof_index + * If set, gives the index of a oneof in the containing type's oneof_decl + * list. This field is a member of that oneof. + * @type string $json_name + * JSON name of this field. The value is set by protocol compiler. If the + * user has set a "json_name" option on this field, that option's value + * will be used. Otherwise, it's deduced from the field's name by converting + * it to camelCase. + * @type \Google\Protobuf\Internal\FieldOptions $options + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php index 169f860be0..751c278d78 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions.php @@ -107,9 +107,73 @@ class FieldOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $ctype + * The ctype option instructs the C++ code generator to use a different + * representation of the field than it normally would. See the specific + * options below. This option is not yet implemented in the open source + * release -- sorry, we'll try to include it in a future version! + * @type bool $packed + * The packed option can be enabled for repeated primitive fields to enable + * a more efficient representation on the wire. Rather than repeatedly + * writing the tag and type for each element, the entire array is encoded as + * a single length-delimited blob. In proto3, only explicit setting it to + * false will avoid using packed encoding. + * @type int $jstype + * The jstype option determines the JavaScript type used for values of the + * field. The option is permitted only for 64 bit integral and fixed types + * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + * is represented as JavaScript string, which avoids loss of precision that + * can happen when a large value is converted to a floating point JavaScript. + * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + * use the JavaScript "number" type. The behavior of the default option + * JS_NORMAL is implementation dependent. + * This option is an enum to permit additional types to be added, e.g. + * goog.math.Integer. + * @type bool $lazy + * Should this field be parsed lazily? Lazy applies only to message-type + * fields. It means that when the outer message is initially parsed, the + * inner message's contents will not be parsed but instead stored in encoded + * form. The inner message will actually be parsed when it is first accessed. + * This is only a hint. Implementations are free to choose whether to use + * eager or lazy parsing regardless of the value of this option. However, + * setting this option true suggests that the protocol author believes that + * using lazy parsing on this field is worth the additional bookkeeping + * overhead typically needed to implement it. + * This option does not affect the public interface of any generated code; + * all method signatures remain the same. Furthermore, thread-safety of the + * interface is not affected by this option; const methods remain safe to + * call from multiple threads concurrently, while non-const methods continue + * to require exclusive access. + * Note that implementations may choose not to check required fields within + * a lazy sub-message. That is, calling IsInitialized() on the outer message + * may return true even if the inner message has missing required fields. + * This is necessary because otherwise the inner message would have to be + * parsed in order to perform the check, defeating the purpose of lazy + * parsing. An implementation which chooses not to check required fields + * must be consistent about it. That is, for any particular sub-message, the + * implementation must either *always* check its required fields, or *never* + * check its required fields, regardless of whether or not the message has + * been parsed. + * @type bool $deprecated + * Is this field deprecated? + * Depending on the target platform, this can emit Deprecated annotations + * for accessors, or it will be completely ignored; in the very least, this + * is a formalization for deprecating fields. + * @type bool $weak + * For Google-internal migration only. Do not use. + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php index 9ee222d19b..cb10aa7939 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php @@ -99,9 +99,42 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message private $syntax = ''; private $has_syntax = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * file name, relative to root of source tree + * @type string $package + * e.g. "foo", "foo.bar", etc. + * @type string[]|\Google\Protobuf\Internal\RepeatedField $dependency + * Names of files imported by this file. + * @type int[]|\Google\Protobuf\Internal\RepeatedField $public_dependency + * Indexes of the public imported files in the dependency list above. + * @type int[]|\Google\Protobuf\Internal\RepeatedField $weak_dependency + * Indexes of the weak imported files in the dependency list. + * For Google-internal migration only. Do not use. + * @type \Google\Protobuf\Internal\DescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $message_type + * All top-level definitions in this file. + * @type \Google\Protobuf\Internal\EnumDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $enum_type + * @type \Google\Protobuf\Internal\ServiceDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $service + * @type \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $extension + * @type \Google\Protobuf\Internal\FileOptions $options + * @type \Google\Protobuf\Internal\SourceCodeInfo $source_code_info + * This field contains optional information about the original source code. + * You may safely remove this entire field without harming runtime + * functionality of the descriptors -- the information is needed only by + * development tools. + * @type string $syntax + * The syntax of the proto file. + * The supported values are "proto2" and "proto3". + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php index 0b2cf95766..9907b17d73 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php @@ -24,9 +24,18 @@ class FileDescriptorSet extends \Google\Protobuf\Internal\Message private $file; private $has_file = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Internal\FileDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $file + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/FileOptions.php b/php/src/Google/Protobuf/Internal/FileOptions.php index 18e9455cb4..2315ed5e2e 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions.php +++ b/php/src/Google/Protobuf/Internal/FileOptions.php @@ -200,9 +200,92 @@ class FileOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $java_package + * Sets the Java package where classes generated from this .proto will be + * placed. By default, the proto package is used, but this is often + * inappropriate because proto packages do not normally start with backwards + * domain names. + * @type string $java_outer_classname + * If set, all the classes from the .proto file are wrapped in a single + * outer class with the given name. This applies to both Proto1 + * (equivalent to the old "--one_java_file" option) and Proto2 (where + * a .proto always translates to a single class, but you may want to + * explicitly choose the class name). + * @type bool $java_multiple_files + * If set true, then the Java code generator will generate a separate .java + * file for each top-level message, enum, and service defined in the .proto + * file. Thus, these types will *not* be nested inside the outer class + * named by java_outer_classname. However, the outer class will still be + * generated to contain the file's getDescriptor() method as well as any + * top-level extensions defined in the file. + * @type bool $java_generate_equals_and_hash + * This option does nothing. + * @type bool $java_string_check_utf8 + * If set true, then the Java2 code generator will generate code that + * throws an exception whenever an attempt is made to assign a non-UTF-8 + * byte sequence to a string field. + * Message reflection will do the same. + * However, an extension field still accepts non-UTF-8 byte sequences. + * This option has no effect on when used with the lite runtime. + * @type int $optimize_for + * @type string $go_package + * Sets the Go package where structs generated from this .proto will be + * placed. If omitted, the Go package will be derived from the following: + * - The basename of the package import path, if provided. + * - Otherwise, the package statement in the .proto file, if present. + * - Otherwise, the basename of the .proto file, without extension. + * @type bool $cc_generic_services + * Should generic services be generated in each language? "Generic" services + * are not specific to any particular RPC system. They are generated by the + * main code generators in each language (without additional plugins). + * Generic services were the only kind of service generation supported by + * early versions of google.protobuf. + * Generic services are now considered deprecated in favor of using plugins + * that generate code specific to your particular RPC system. Therefore, + * these default to false. Old code which depends on generic services should + * explicitly set them to true. + * @type bool $java_generic_services + * @type bool $py_generic_services + * @type bool $php_generic_services + * @type bool $deprecated + * Is this file deprecated? + * Depending on the target platform, this can emit Deprecated annotations + * for everything in the file, or it will be completely ignored; in the very + * least, this is a formalization for deprecating files. + * @type bool $cc_enable_arenas + * Enables the use of arenas for the proto messages in this file. This applies + * only to generated classes for C++. + * @type string $objc_class_prefix + * Sets the objective c class prefix which is prepended to all objective c + * generated classes from this .proto. There is no default. + * @type string $csharp_namespace + * Namespace for generated classes; defaults to the package. + * @type string $swift_prefix + * By default Swift generators will take the proto package and CamelCase it + * replacing '.' with underscore and use that to prefix the types/symbols + * defined. When this options is provided, they will use this value instead + * to prefix the types/symbols defined. + * @type string $php_class_prefix + * Sets the php class prefix which is prepended to all php generated classes + * from this .proto. Default is empty. + * @type string $php_namespace + * Use this option to change the namespace of php generated classes. Default + * is empty. When this option is empty, the package name will be used for + * determining the namespace. + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. + * See the documentation for the "Options" section above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php index ae2ad74558..c2b41a2982 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php @@ -28,9 +28,20 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message private $annotation; private $has_annotation = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation[]|\Google\Protobuf\Internal\RepeatedField $annotation + * An Annotation connects some span of text in generated code to an element + * of its generating .proto file. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php index 22ac2337c6..75182007d3 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php @@ -48,9 +48,29 @@ class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message private $end = 0; private $has_end = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int[]|\Google\Protobuf\Internal\RepeatedField $path + * Identifies the element in the original source .proto file. This field + * is formatted the same as SourceCodeInfo.Location.path. + * @type string $source_file + * Identifies the filesystem path to the original source .proto. + * @type int $begin + * Identifies the starting offset in bytes in the generated code + * that relates to the identified object. + * @type int $end + * Identifies the ending offset in bytes in the generated code that + * relates to the identified offset. The end offset should be one past + * the last relevant byte (so the length of the text = end - begin). + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 3aff7bd623..73ac375e5e 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -66,19 +66,30 @@ class Message /** * @ignore */ - public function __construct($desc = NULL) + public function __construct($data = NULL) { // MapEntry message is shared by all types of map fields, whose // descriptors are different from each other. Thus, we cannot find a // specific descriptor from the descriptor pool. - if (get_class($this) === 'Google\Protobuf\Internal\MapEntry') { - $this->desc = $desc; - foreach ($desc->getField() as $field) { - $setter = $field->getSetter(); - $this->$setter($this->defaultValue($field)); + if ($this instanceof MapEntry) { + $this->initWithDescriptor($data); + } else { + $this->initWithGeneratedPool(); + if (is_array($data)) { + $this->mergeFromArray($data); + } else if (!empty($data)) { + throw new \InvalidArgumentException( + 'Message constructor must be an array or null.' + ); } - return; } + } + + /** + * @ignore + */ + private function initWithGeneratedPool() + { $pool = DescriptorPool::getGeneratedPool(); $this->desc = $pool->getDescriptorByClassName(get_class($this)); if (is_null($this->desc)) { @@ -151,6 +162,19 @@ class Message } } + /** + * @ignore + */ + private function initWithDescriptor(Descriptor $desc) + { + $this->desc = $desc; + foreach ($desc->getField() as $field) { + $setter = $field->getSetter(); + $defaultValue = $this->defaultValue($field); + $this->$setter($defaultValue); + } + } + protected function readOneof($number) { $field = $this->desc->getFieldByNumber($number); @@ -628,58 +652,58 @@ class Message */ public function mergeFrom($msg) { - if (get_class($this) !== get_class($msg)) { - user_error("Cannot merge messages with different class."); - return; - } - - foreach ($this->desc->getField() as $field) { - $setter = $field->getSetter(); - $getter = $field->getGetter(); - if ($field->isMap()) { - if (count($msg->$getter()) != 0) { - $value_field = $field->getMessageType()->getFieldByNumber(2); - foreach ($msg->$getter() as $key => $value) { - if ($value_field->getType() == GPBType::MESSAGE) { - $klass = $value_field->getMessageType()->getClass(); - $copy = new $klass; - $copy->mergeFrom($value); - - $this->kvUpdateHelper($field, $key, $copy); - } else { - $this->kvUpdateHelper($field, $key, $value); - } - } - } - } else if ($field->getLabel() === GPBLabel::REPEATED) { - if (count($msg->$getter()) != 0) { - foreach ($msg->$getter() as $tmp) { - if ($field->getType() == GPBType::MESSAGE) { - $klass = $field->getMessageType()->getClass(); - $copy = new $klass; - $copy->mergeFrom($tmp); - $this->appendHelper($field, $copy); - } else { - $this->appendHelper($field, $tmp); - } - } - } - } else if ($field->getLabel() === GPBLabel::OPTIONAL) { - if($msg->$getter() !== $this->defaultValue($field)) { - $tmp = $msg->$getter(); - if ($field->getType() == GPBType::MESSAGE) { - if (is_null($this->$getter())) { - $klass = $field->getMessageType()->getClass(); - $new_msg = new $klass; - $this->$setter($new_msg); - } - $this->$getter()->mergeFrom($tmp); - } else { - $this->$setter($tmp); - } - } - } - } + if (get_class($this) !== get_class($msg)) { + user_error("Cannot merge messages with different class."); + return; + } + + foreach ($this->desc->getField() as $field) { + $setter = $field->getSetter(); + $getter = $field->getGetter(); + if ($field->isMap()) { + if (count($msg->$getter()) != 0) { + $value_field = $field->getMessageType()->getFieldByNumber(2); + foreach ($msg->$getter() as $key => $value) { + if ($value_field->getType() == GPBType::MESSAGE) { + $klass = $value_field->getMessageType()->getClass(); + $copy = new $klass; + $copy->mergeFrom($value); + + $this->kvUpdateHelper($field, $key, $copy); + } else { + $this->kvUpdateHelper($field, $key, $value); + } + } + } + } else if ($field->getLabel() === GPBLabel::REPEATED) { + if (count($msg->$getter()) != 0) { + foreach ($msg->$getter() as $tmp) { + if ($field->getType() == GPBType::MESSAGE) { + $klass = $field->getMessageType()->getClass(); + $copy = new $klass; + $copy->mergeFrom($tmp); + $this->appendHelper($field, $copy); + } else { + $this->appendHelper($field, $tmp); + } + } + } + } else if ($field->getLabel() === GPBLabel::OPTIONAL) { + if($msg->$getter() !== $this->defaultValue($field)) { + $tmp = $msg->$getter(); + if ($field->getType() == GPBType::MESSAGE) { + if (is_null($this->$getter())) { + $klass = $field->getMessageType()->getClass(); + $new_msg = new $klass; + $this->$setter($new_msg); + } + $this->$getter()->mergeFrom($tmp); + } else { + $this->$setter($tmp); + } + } + } + } } /** @@ -763,7 +787,8 @@ class Message try { $timestamp = GPBUtil::parseTimestamp($value); } catch (\Exception $e) { - throw new GPBDecodeException("Invalid RFC 3339 timestamp: ".$e->getMessage()); + throw new GPBDecodeException( + "Invalid RFC 3339 timestamp: ".$e->getMessage()); } $submsg->setSeconds($timestamp->getSeconds()); @@ -775,7 +800,8 @@ class Message try { return GPBUtil::parseFieldMask($value); } catch (\Exception $e) { - throw new GPBDecodeException("Invalid FieldMask: ".$e->getMessage()); + throw new GPBDecodeException( + "Invalid FieldMask: ".$e->getMessage()); } } else { if (is_null($value) && @@ -792,21 +818,23 @@ class Message case GPBType::ENUM: if (is_null($value)) { return $this->defaultValue($field); - } else if (is_integer($value)) { + } + if (is_integer($value)) { return $value; - } else { - $enum_value = - $field->getEnumType()->getValueByName($value); } + $enum_value = $field->getEnumType()->getValueByName($value); if (!is_null($enum_value)) { return $enum_value->getNumber(); } + throw new GPBDecodeException( + "Enum field only accepts integer or enum value name"); case GPBType::STRING: if (is_null($value)) { return $this->defaultValue($field); } if (!is_string($value)) { - throw new GPBDecodeException("Expect string"); + throw new GPBDecodeException( + "String field only accepts string value"); } return $value; case GPBType::BYTES: @@ -814,12 +842,12 @@ class Message return $this->defaultValue($field); } if (!is_string($value)) { - throw new GPBDecodeException("Expect string"); + throw new GPBDecodeException( + "Byte field only accepts string value"); } $proto_value = base64_decode($value, true); if ($proto_value === false) { - throw new GPBDecodeException( - "Invalid base64 characters"); + throw new GPBDecodeException("Invalid base64 characters"); } return $proto_value; case GPBType::BOOL: @@ -834,27 +862,14 @@ class Message return false; } throw new GPBDecodeException( - "Bool field only accept bool value"); + "Bool field only accepts bool value"); } if (!is_bool($value)) { throw new GPBDecodeException( - "Bool field only accept bool value"); + "Bool field only accepts bool value"); } return $value; case GPBType::FLOAT: - if (is_null($value)) { - return $this->defaultValue($field); - } - if ($value === "Infinity") { - return INF; - } - if ($value === "-Infinity") { - return -INF; - } - if ($value === "NaN") { - return NAN; - } - return $value; case GPBType::DOUBLE: if (is_null($value)) { return $this->defaultValue($field); @@ -943,6 +958,39 @@ class Message } } + /** + * Populates the message from a user-supplied PHP array. Array keys + * correspond to Message properties and nested message properties. + * + * Example: + * ``` + * $message->mergeFromArray([ + * 'name' => 'This is a message name', + * 'interval' => [ + * 'startTime' => time() - 60, + * 'endTime' => time(), + * ] + * ]); + * ``` + * + * @param array $array An array containing message properties and values. + * @return null. + * @throws Exception Invalid data. + */ + protected function mergeFromArray(array $array) + { + // Just call the setters for the field names + foreach ($array as $key => $value) { + $field = $this->desc->getFieldByName($key); + if (is_null($field)) { + throw new \UnexpectedValueException( + 'Invalid message property: ' . $key); + } + $setter = $field->getSetter(); + $this->$setter($value); + } + } + protected function mergeFromJsonArray($array) { if (is_a($this, "Google\Protobuf\Any")) { @@ -1035,6 +1083,11 @@ class Message } return; } + $this->mergeFromArrayJsonImpl($array); + } + + private function mergeFromArrayJsonImpl($array) + { foreach ($array as $key => $value) { $field = $this->desc->getFieldByJsonName($key); if (is_null($field)) { @@ -1043,7 +1096,6 @@ class Message continue; } } - $setter = $field->getSetter(); if ($field->isMap()) { if (is_null($value)) { continue; @@ -1055,15 +1107,13 @@ class Message throw new \Exception( "Map value field element cannot be null."); } - $proto_key = - $this->convertJsonValueToProtoValue( - $tmp_key, - $key_field, - true); - $proto_value = - $this->convertJsonValueToProtoValue( - $tmp_value, - $value_field); + $proto_key = $this->convertJsonValueToProtoValue( + $tmp_key, + $key_field, + true); + $proto_value = $this->convertJsonValueToProtoValue( + $tmp_value, + $value_field); self::kvUpdateHelper($field, $proto_key, $proto_value); } } else if ($field->isRepeated()) { @@ -1075,14 +1125,16 @@ class Message throw new \Exception( "Repeated field elements cannot be null."); } - $proto_value = - $this->convertJsonValueToProtoValue($tmp, $field); + $proto_value = $this->convertJsonValueToProtoValue( + $tmp, + $field); self::appendHelper($field, $proto_value); } } else { $setter = $field->getSetter(); - $proto_value = - $this->convertJsonValueToProtoValue($value, $field); + $proto_value = $this->convertJsonValueToProtoValue( + $value, + $field); if ($field->getType() === GPBType::MESSAGE) { if (is_null($proto_value)) { continue; diff --git a/php/src/Google/Protobuf/Internal/MessageOptions.php b/php/src/Google/Protobuf/Internal/MessageOptions.php index 99ff3d0ee2..bf490de686 100644 --- a/php/src/Google/Protobuf/Internal/MessageOptions.php +++ b/php/src/Google/Protobuf/Internal/MessageOptions.php @@ -87,9 +87,63 @@ class MessageOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type bool $message_set_wire_format + * Set true to use the old proto1 MessageSet wire format for extensions. + * This is provided for backwards-compatibility with the MessageSet wire + * format. You should not use this for any other reason: It's less + * efficient, has fewer features, and is more complicated. + * The message must be defined exactly as follows: + * message Foo { + * option message_set_wire_format = true; + * extensions 4 to max; + * } + * Note that the message cannot have any defined fields; MessageSets only + * have extensions. + * All extensions of your type must be singular messages; e.g. they cannot + * be int32s, enums, or repeated messages. + * Because this is an option, the above two restrictions are not enforced by + * the protocol compiler. + * @type bool $no_standard_descriptor_accessor + * Disables the generation of the standard "descriptor()" accessor, which can + * conflict with a field of the same name. This is meant to make migration + * from proto1 easier; new code should avoid fields named "descriptor". + * @type bool $deprecated + * Is this message deprecated? + * Depending on the target platform, this can emit Deprecated annotations + * for the message, or it will be completely ignored; in the very least, + * this is a formalization for deprecating messages. + * @type bool $map_entry + * Whether the message is an automatically generated map entry type for the + * maps field. + * For maps fields: + * map map_field = 1; + * The parsed descriptor looks like: + * message MapFieldEntry { + * option map_entry = true; + * optional KeyType key = 1; + * optional ValueType value = 2; + * } + * repeated MapFieldEntry map_field = 1; + * Implementations may choose not to generate the map_entry=true message, but + * use a native map in the target language to hold the keys and values. + * The reflection APIs in such implementions still need to work as + * if the field is a repeated message field. + * NOTE: Do not set the option in .proto files. Always use the maps syntax + * instead. The option should only be implicitly set by the proto compiler + * parser. + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php index ccfce2dbd6..1bd5dd3e1c 100644 --- a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php @@ -55,9 +55,27 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message private $server_streaming = false; private $has_server_streaming = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * @type string $input_type + * Input and output type names. These are resolved in the same way as + * FieldDescriptorProto.type_name, but must refer to a message type. + * @type string $output_type + * @type \Google\Protobuf\Internal\MethodOptions $options + * @type bool $client_streaming + * Identifies if client streams multiple client messages + * @type bool $server_streaming + * Identifies if server streams multiple server messages + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/MethodOptions.php b/php/src/Google/Protobuf/Internal/MethodOptions.php index baa806b7aa..a2c729a9bb 100644 --- a/php/src/Google/Protobuf/Internal/MethodOptions.php +++ b/php/src/Google/Protobuf/Internal/MethodOptions.php @@ -38,9 +38,25 @@ class MethodOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type bool $deprecated + * Is this method deprecated? + * Depending on the target platform, this can emit Deprecated annotations + * for the method, or it will be completely ignored; in the very least, + * this is a formalization for deprecating methods. + * @type int $idempotency_level + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php index 15ff061074..9ecfe5cbfe 100644 --- a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php @@ -28,9 +28,19 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message private $options = null; private $has_options = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * @type \Google\Protobuf\Internal\OneofOptions $options + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/OneofOptions.php b/php/src/Google/Protobuf/Internal/OneofOptions.php index e5b4633d59..46b516f301 100644 --- a/php/src/Google/Protobuf/Internal/OneofOptions.php +++ b/php/src/Google/Protobuf/Internal/OneofOptions.php @@ -23,9 +23,19 @@ class OneofOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php index da88e9c444..8de7afd0bc 100644 --- a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php @@ -33,9 +33,20 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message private $options = null; private $has_options = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * @type \Google\Protobuf\Internal\MethodDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $method + * @type \Google\Protobuf\Internal\ServiceOptions $options + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/ServiceOptions.php b/php/src/Google/Protobuf/Internal/ServiceOptions.php index 3e7214a1eb..67162f3764 100644 --- a/php/src/Google/Protobuf/Internal/ServiceOptions.php +++ b/php/src/Google/Protobuf/Internal/ServiceOptions.php @@ -33,9 +33,24 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message private $uninterpreted_option; private $has_uninterpreted_option = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type bool $deprecated + * Is this service deprecated? + * Depending on the target platform, this can emit Deprecated annotations + * for the service, or it will be completely ignored; in the very least, + * this is a formalization for deprecating services. + * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option + * The parser stores options it doesn't recognize here. See above. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php index 6ce05ed420..2305a79201 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php @@ -66,9 +66,59 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message private $location; private $has_location = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Internal\SourceCodeInfo_Location[]|\Google\Protobuf\Internal\RepeatedField $location + * A Location identifies a piece of source code in a .proto file which + * corresponds to a particular definition. This information is intended + * to be useful to IDEs, code indexers, documentation generators, and similar + * tools. + * For example, say we have a file like: + * message Foo { + * optional string foo = 1; + * } + * Let's look at just the field definition: + * optional string foo = 1; + * ^ ^^ ^^ ^ ^^^ + * a bc de f ghi + * We have the following locations: + * span path represents + * [a,i) [ 4, 0, 2, 0 ] The whole field definition. + * [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + * [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + * [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + * [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + * Notes: + * - A location may refer to a repeated field itself (i.e. not to any + * particular index within it). This is used whenever a set of elements are + * logically enclosed in a single code segment. For example, an entire + * extend block (possibly containing multiple extension definitions) will + * have an outer location whose path refers to the "extensions" repeated + * field without an index. + * - Multiple locations may have the same path. This happens when a single + * logical declaration is spread out across multiple places. The most + * obvious example is the "extend" block again -- there may be multiple + * extend blocks in the same scope, each of which will have the same path. + * - A location's span is not always a subset of its parent's span. For + * example, the "extendee" of an extension declaration appears at the + * beginning of the "extend" block and is shared by all extensions within + * the block. + * - Just because a location's span is a subset of some other location's span + * does not mean that it is a descendent. For example, a "group" defines + * both a type and a field in a single declaration. Thus, the locations + * corresponding to the type and field and their components will overlap. + * - Code which tries to interpret locations should probably be designed to + * ignore those that it doesn't understand, as more types of locations could + * be recorded in the future. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php index 19ed2bc229..f930aac101 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php @@ -106,9 +106,84 @@ class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message private $leading_detached_comments; private $has_leading_detached_comments = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int[]|\Google\Protobuf\Internal\RepeatedField $path + * Identifies which part of the FileDescriptorProto was defined at this + * location. + * Each element is a field number or an index. They form a path from + * the root FileDescriptorProto to the place where the definition. For + * example, this path: + * [ 4, 3, 2, 7, 1 ] + * refers to: + * file.message_type(3) // 4, 3 + * .field(7) // 2, 7 + * .name() // 1 + * This is because FileDescriptorProto.message_type has field number 4: + * repeated DescriptorProto message_type = 4; + * and DescriptorProto.field has field number 2: + * repeated FieldDescriptorProto field = 2; + * and FieldDescriptorProto.name has field number 1: + * optional string name = 1; + * Thus, the above path gives the location of a field name. If we removed + * the last element: + * [ 4, 3, 2, 7 ] + * this path refers to the whole field declaration (from the beginning + * of the label to the terminating semicolon). + * @type int[]|\Google\Protobuf\Internal\RepeatedField $span + * Always has exactly three or four elements: start line, start column, + * end line (optional, otherwise assumed same as start line), end column. + * These are packed into a single field for efficiency. Note that line + * and column numbers are zero-based -- typically you will want to add + * 1 to each before displaying to a user. + * @type string $leading_comments + * If this SourceCodeInfo represents a complete declaration, these are any + * comments appearing before and after the declaration which appear to be + * attached to the declaration. + * A series of line comments appearing on consecutive lines, with no other + * tokens appearing on those lines, will be treated as a single comment. + * leading_detached_comments will keep paragraphs of comments that appear + * before (but not connected to) the current element. Each paragraph, + * separated by empty lines, will be one comment element in the repeated + * field. + * Only the comment content is provided; comment markers (e.g. //) are + * stripped out. For block comments, leading whitespace and an asterisk + * will be stripped from the beginning of each line other than the first. + * Newlines are included in the output. + * Examples: + * optional int32 foo = 1; // Comment attached to foo. + * // Comment attached to bar. + * optional int32 bar = 2; + * optional string baz = 3; + * // Comment attached to baz. + * // Another line attached to baz. + * // Comment attached to qux. + * // + * // Another line attached to qux. + * optional double qux = 4; + * // Detached comment for corge. This is not leading or trailing comments + * // to qux or corge because there are blank lines separating it from + * // both. + * // Detached comment for corge paragraph 2. + * optional string corge = 5; + * /* Block comment attached + * * to corge. Leading asterisks + * * will be removed. */ + * /* Block comment attached to + * * grault. */ + * optional int32 grault = 6; + * // ignored detached comments. + * @type string $trailing_comments + * @type string[]|\Google\Protobuf\Internal\RepeatedField $leading_detached_comments + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption.php b/php/src/Google/Protobuf/Internal/UninterpretedOption.php index 4d342eb33b..36a18688cf 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption.php @@ -61,9 +61,26 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message private $aggregate_value = ''; private $has_aggregate_value = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Internal\UninterpretedOption_NamePart[]|\Google\Protobuf\Internal\RepeatedField $name + * @type string $identifier_value + * The value of the uninterpreted option, in whatever type the tokenizer + * identified it as during parsing. Exactly one of these should be set. + * @type int|string $positive_int_value + * @type int|string $negative_int_value + * @type float $double_value + * @type string $string_value + * @type string $aggregate_value + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php b/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php index c9a6fc3c7f..d4369fda4c 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php @@ -32,9 +32,19 @@ class UninterpretedOption_NamePart extends \Google\Protobuf\Internal\Message private $is_extension = false; private $has_is_extension = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name_part + * @type bool $is_extension + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/tests/generated_phpdoc_test.php b/php/tests/generated_phpdoc_test.php index 6c1a26f7a2..505dafea73 100644 --- a/php/tests/generated_phpdoc_test.php +++ b/php/tests/generated_phpdoc_test.php @@ -16,6 +16,14 @@ class GeneratedPhpdocTest extends TestBase $this->assertContains('foo.TestMessage', $doc); } + public function testPhpDocForConstructor() + { + $class = new ReflectionClass('Foo\TestMessage'); + $doc = $class->getMethod('__construct')->getDocComment(); + $this->assertContains('@param array $data', $doc); + $this->assertContains('@type int $optional_int32', $doc); + } + /** * @dataProvider providePhpDocForGettersAndSetters */ diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php index 5dbc9233cf..720af1323c 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/php_implementation_test.php @@ -3,6 +3,7 @@ require_once('test_base.php'); require_once('test_util.php'); +use Foo\TestEnum; use Foo\TestMessage; use Foo\TestMessage_Sub; use Foo\TestPackedMessage; @@ -15,7 +16,6 @@ use Google\Protobuf\Internal\CodedOutputStream; class ImplementationTest extends TestBase { - public function testReadInt32() { $value = null; @@ -513,4 +513,156 @@ class ImplementationTest extends TestBase TestUtil::setTestPackedMessage($m); $this->assertSame(166, $m->byteSize()); } + + public function testArrayConstructor() + { + $m = new TestMessage([ + 'optional_int32' => -42, + 'optional_int64' => -43, + 'optional_uint32' => 42, + 'optional_uint64' => 43, + 'optional_sint32' => -44, + 'optional_sint64' => -45, + 'optional_fixed32' => 46, + 'optional_fixed64' => 47, + 'optional_sfixed32' => -46, + 'optional_sfixed64' => -47, + 'optional_float' => 1.5, + 'optional_double' => 1.6, + 'optional_bool' => true, + 'optional_string' => 'a', + 'optional_bytes' => 'b', + 'optional_enum' => TestEnum::ONE, + 'optional_message' => new TestMessage_Sub([ + 'a' => 33 + ]), + 'repeated_int32' => [-42, -52], + 'repeated_int64' => [-43, -53], + 'repeated_uint32' => [42, 52], + 'repeated_uint64' => [43, 53], + 'repeated_sint32' => [-44, -54], + 'repeated_sint64' => [-45, -55], + 'repeated_fixed32' => [46, 56], + 'repeated_fixed64' => [47, 57], + 'repeated_sfixed32' => [-46, -56], + 'repeated_sfixed64' => [-47, -57], + 'repeated_float' => [1.5, 2.5], + 'repeated_double' => [1.6, 2.6], + 'repeated_bool' => [true, false], + 'repeated_string' => ['a', 'c'], + 'repeated_bytes' => ['b', 'd'], + 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], + 'repeated_message' => [ + new TestMessage_Sub(['a' => 34]), + new TestMessage_Sub(['a' => 35]), + ], + 'map_int32_int32' => [-62 => -62], + 'map_int64_int64' => [-63 => -63], + 'map_uint32_uint32' => [62 => 62], + 'map_uint64_uint64' => [63 => 63], + 'map_sint32_sint32' => [-64 => -64], + 'map_sint64_sint64' => [-65 => -65], + 'map_fixed32_fixed32' => [66 => 66], + 'map_fixed64_fixed64' => [67 => 67], + 'map_sfixed32_sfixed32' => [-68 => -68], + 'map_sfixed64_sfixed64' => [-69 => -69], + 'map_int32_float' => [1 => 3.5], + 'map_int32_double' => [1 => 3.6], + 'map_bool_bool' => [true => true], + 'map_string_string' => ['e' => 'e'], + 'map_int32_bytes' => [1 => 'f'], + 'map_int32_enum' => [1 => TestEnum::ONE], + 'map_int32_message' => [1 => new TestMessage_Sub(['a' => 36])], + ]); + + TestUtil::assertTestMessage($m); + + // Using message objects + $m = new TestMessage([ + 'optional_message' => new TestMessage_Sub(['a' => 33]), + 'repeated_message' => [ + new TestMessage_Sub(['a' => 34]), + new TestMessage_Sub(['a' => 35]), + ], + 'map_int32_message' => [ + 1 => new TestMessage_Sub(['a' => 36]) + ], + ]); + + $this->assertEquals(33, $m->getOptionalMessage()->getA()); + $this->assertEquals(34, $m->getRepeatedMessage()[0]->getA()); + $this->assertEquals(35, $m->getRepeatedMessage()[1]->getA()); + $this->assertEquals(36, $m->getMapInt32Message()[1]->getA()); + } + + /** + * @expectedException UnexpectedValueException + * @expectedExceptionMessage Invalid message property: optionalInt32 + */ + public function testArrayConstructorJsonCaseThrowsException() + { + $m = new TestMessage([ + 'optionalInt32' => -42, + ]); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Expect message. + */ + public function testArraysForMessagesThrowsException() + { + $m = new TestMessage([ + 'optional_message' => [ + 'a' => 33 + ] + ]); + } + + public function testArrayConstructorWithNullValues() + { + $requestData = [ + 'optional_bool' => null, + 'optional_string' => null, + 'optional_bytes' => null, + 'optional_message' => null, + ]; + + $m = new TestMessage($requestData); + + $this->assertSame(false, $m->getOptionalBool()); + $this->assertSame('', $m->getOptionalString()); + $this->assertSame('', $m->getOptionalBytes()); + $this->assertSame(null, $m->getOptionalMessage()); + } + + /** + * @dataProvider provideArrayConstructorWithNullValuesThrowsException + * @expectedException Exception + */ + public function testArrayConstructorWithNullValuesThrowsException($requestData) + { + $m = new TestMessage($requestData); + } + + public function provideArrayConstructorWithNullValuesThrowsException() + { + return [ + [['optional_int32' => null]], + [['optional_int64' => null]], + [['optional_uint32' => null]], + [['optional_uint64' => null]], + [['optional_sint32' => null]], + [['optional_sint64' => null]], + [['optional_fixed32' => null]], + [['optional_fixed64' => null]], + [['optional_sfixed32' => null]], + [['optional_sfixed64' => null]], + [['optional_float' => null]], + [['optional_double' => null]], + [['optional_enum' => null]], + [['repeated_int32' => null]], + [['map_int32_int32' => null]], + ]; + } } diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index a37380e362..34d0f9efe2 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -94,6 +94,9 @@ void Indent(io::Printer* printer); void Outdent(io::Printer* printer); void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, int is_descriptor); +void GenerateMessageConstructorDocComment(io::Printer* printer, + const Descriptor* message, + int is_descriptor); void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, int is_descriptor, int function_type); void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, @@ -1109,8 +1112,9 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, } printer.Print("\n"); + GenerateMessageConstructorDocComment(&printer, message, is_descriptor); printer.Print( - "public function __construct() {\n"); + "public function __construct($data = NULL) {\n"); Indent(&printer); std::string metadata_filename = @@ -1118,7 +1122,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, std::string metadata_fullname = FilenameToClassname(metadata_filename); printer.Print( "\\^fullname^::initOnce();\n" - "parent::__construct();\n", + "parent::__construct($data);\n", "fullname", metadata_fullname); Outdent(&printer); @@ -1271,7 +1275,8 @@ static string EscapePhpdoc(const string& input) { } static void GenerateDocCommentBodyForLocation( - io::Printer* printer, const SourceLocation& location) { + io::Printer* printer, const SourceLocation& location, bool trailingNewline, + int indentCount) { string comments = location.leading_comments.empty() ? location.trailing_comments : location.leading_comments; if (!comments.empty()) { @@ -1292,14 +1297,16 @@ static void GenerateDocCommentBodyForLocation( // Most lines should start with a space. Watch out for lines that start // with a /, since putting that right after the leading asterisk will // close the comment. - if (!lines[i].empty() && lines[i][0] == '/') { + if (indentCount == 0 && !lines[i].empty() && lines[i][0] == '/') { printer->Print(" * ^line^\n", "line", lines[i]); } else { - printer->Print(" *^line^\n", "line", lines[i]); + std::string indent = std::string(indentCount, ' '); + printer->Print(" *^ind^^line^\n", "ind", indent, "line", lines[i]); } } - printer->Print( - " *\n"); + if (trailingNewline) { + printer->Print(" *\n"); + } } } @@ -1308,7 +1315,7 @@ static void GenerateDocCommentBody( io::Printer* printer, const DescriptorType* descriptor) { SourceLocation location; if (descriptor->GetSourceLocation(&location)) { - GenerateDocCommentBodyForLocation(printer, location); + GenerateDocCommentBodyForLocation(printer, location, true, 0); } } @@ -1334,6 +1341,37 @@ void GenerateMessageDocComment(io::Printer* printer, "messagename", EscapePhpdoc(message->full_name())); } +void GenerateMessageConstructorDocComment(io::Printer* printer, + const Descriptor* message, + int is_descriptor) { + // In theory we should have slightly different comments for setters, getters, + // etc., but in practice everyone already knows the difference between these + // so it's redundant information. + + // We start the comment with the main body based on the comments from the + // .proto file (if present). We then end with the field declaration, e.g.: + // optional string foo = 5; + // If the field is a group, the debug string might end with {. + printer->Print("/**\n"); + printer->Print(" * Constructor.\n"); + printer->Print(" *\n"); + printer->Print(" * @param array $data {\n"); + printer->Print(" * Optional. Data for populating the Message object.\n"); + printer->Print(" *\n"); + for (int i = 0; i < message->field_count(); i++) { + const FieldDescriptor* field = message->field(i); + printer->Print(" * @type ^php_type^ $^var^\n", + "php_type", PhpSetterTypeName(field, is_descriptor), + "var", field->name()); + SourceLocation location; + if (field->GetSourceLocation(&location)) { + GenerateDocCommentBodyForLocation(printer, location, false, 10); + } + } + printer->Print(" * }\n"); + printer->Print(" */\n"); +} + void GenerateServiceDocComment(io::Printer* printer, const ServiceDescriptor* service) { printer->Print("/**\n"); From 8b336f8c5a77ca4932b00203e485f9266f6f0c30 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Thu, 3 May 2018 10:29:23 -0700 Subject: [PATCH 08/28] Implement array constructor in php c extension. --- php/ext/google/protobuf/message.c | 111 +++++++++++++++++++++++++- php/tests/generated_class_test.php | 66 +++++++++++++++ php/tests/php_implementation_test.php | 81 ------------------- 3 files changed, 173 insertions(+), 85 deletions(-) diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index c8f4d62b66..5a8734bc32 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -282,15 +282,118 @@ void build_class_from_descriptor( // PHP Methods // ----------------------------------------------------------------------------- +void Message_construct(zval* msg, zval* array_wrapper) { + zend_class_entry* ce = Z_OBJCE_P(msg); + MessageHeader* intern = NULL; + if (EXPECTED(class_added(ce))) { + intern = UNBOX(MessageHeader, msg); + custom_data_init(ce, intern PHP_PROTO_TSRMLS_CC); + } + + if (array_wrapper == NULL) { + return; + } + + HashTable* array = Z_ARRVAL_P(array_wrapper); + HashPosition pointer; + zval key; + void* value; + const upb_fielddef* field; + + for (zend_hash_internal_pointer_reset_ex(array, &pointer); + php_proto_zend_hash_get_current_data_ex(array, (void**)&value, + &pointer) == SUCCESS; + zend_hash_move_forward_ex(array, &pointer)) { + zend_hash_get_current_key_zval_ex(array, &key, &pointer); + field = upb_msgdef_ntofz(intern->descriptor->msgdef, Z_STRVAL_P(&key)); + if (field == NULL) { + zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(&key)); + } + if (upb_fielddef_ismap(field)) { + PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg)); + zval* submap = message_get_property_internal(msg, &key TSRMLS_CC); + PHP_PROTO_FAKE_SCOPE_END; + HashTable* subtable = HASH_OF( + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)); + HashPosition subpointer; + zval subkey; + void* memory; + for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer); + php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory, + &subpointer) == SUCCESS; + zend_hash_move_forward_ex(subtable, &subpointer)) { + zend_hash_get_current_key_zval_ex(subtable, &subkey, &subpointer); + map_field_handlers->write_dimension( + submap, &subkey, + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); + zval_dtor(&subkey); + } + } else if (upb_fielddef_isseq(field)) { + PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg)); + zval* subarray = message_get_property_internal(msg, &key TSRMLS_CC); + PHP_PROTO_FAKE_SCOPE_END; + HashTable* subtable = HASH_OF( + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)); + HashPosition subpointer; + void* memory; + for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer); + php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory, + &subpointer) == SUCCESS; + zend_hash_move_forward_ex(subtable, &subpointer)) { + repeated_field_handlers->write_dimension( + subarray, NULL, + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); + } + } else if (upb_fielddef_issubmsg(field)) { + const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field); + PHP_PROTO_HASHTABLE_VALUE desc_php = get_def_obj(submsgdef); + Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, desc_php); + zend_property_info* property_info; + PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg)); +#if PHP_MAJOR_VERSION < 7 + property_info = + zend_get_property_info(Z_OBJCE_P(msg), &key, true TSRMLS_CC); +#else + property_info = + zend_get_property_info(Z_OBJCE_P(msg), Z_STR_P(&key), true); +#endif + PHP_PROTO_FAKE_SCOPE_END; + CACHED_VALUE* cached = OBJ_PROP(Z_OBJ_P(msg), property_info->offset); +#if PHP_MAJOR_VERSION < 7 + SEPARATE_ZVAL_IF_NOT_REF(cached); +#endif + zval* submsg = CACHED_PTR_TO_ZVAL_PTR(cached); + ZVAL_OBJ(submsg, desc->klass->create_object(desc->klass TSRMLS_CC)); + Message_construct(submsg, NULL); + MessageHeader* from = UNBOX(MessageHeader, + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)); + MessageHeader* to = UNBOX(MessageHeader, submsg); + if(from->descriptor != to->descriptor) { + zend_error(E_USER_ERROR, "Cannot merge messages with different class."); + return; + } + + layout_merge(from->descriptor->layout, from, to TSRMLS_CC); + } else { + message_set_property_internal(msg, &key, + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value) TSRMLS_CC); + } + zval_dtor(&key); + } +} + // At the first time the message is created, the class entry hasn't been // modified. As a result, the first created instance will be a normal zend // object. Here, we manually modify it to our message in such a case. PHP_METHOD(Message, __construct) { - zend_class_entry* ce = Z_OBJCE_P(getThis()); - if (EXPECTED(class_added(ce))) { - MessageHeader* intern = UNBOX(MessageHeader, getThis()); - custom_data_init(ce, intern PHP_PROTO_TSRMLS_CC); + // Init message with array + zval* array_wrapper; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!", &array_wrapper, + message_type) == FAILURE) { + return; } + + Message_construct(getThis(), array_wrapper); } PHP_METHOD(Message, clear) { diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 53d18ee771..fbee29bc5b 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -1171,4 +1171,70 @@ class GeneratedClassTest extends TestBase $m = new testLowerCaseMessage(); $n = testLowerCaseEnum::VALUE; } + + ######################################################### + # Test Array Constructor. + ######################################################### + + public function testArrayConstructor() + { + $m = new TestMessage([ + 'optional_int32' => -42, + 'optional_int64' => -43, + 'optional_uint32' => 42, + 'optional_uint64' => 43, + 'optional_sint32' => -44, + 'optional_sint64' => -45, + 'optional_fixed32' => 46, + 'optional_fixed64' => 47, + 'optional_sfixed32' => -46, + 'optional_sfixed64' => -47, + 'optional_float' => 1.5, + 'optional_double' => 1.6, + 'optional_bool' => true, + 'optional_string' => 'a', + 'optional_bytes' => 'b', + 'optional_enum' => TestEnum::ONE, + 'optional_message' => new TestMessage_Sub([ + 'a' => 33 + ]), + 'repeated_int32' => [-42, -52], + 'repeated_int64' => [-43, -53], + 'repeated_uint32' => [42, 52], + 'repeated_uint64' => [43, 53], + 'repeated_sint32' => [-44, -54], + 'repeated_sint64' => [-45, -55], + 'repeated_fixed32' => [46, 56], + 'repeated_fixed64' => [47, 57], + 'repeated_sfixed32' => [-46, -56], + 'repeated_sfixed64' => [-47, -57], + 'repeated_float' => [1.5, 2.5], + 'repeated_double' => [1.6, 2.6], + 'repeated_bool' => [true, false], + 'repeated_string' => ['a', 'c'], + 'repeated_bytes' => ['b', 'd'], + 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], + 'repeated_message' => [new TestMessage_Sub(['a' => 34]), + new TestMessage_Sub(['a' => 35])], + 'map_int32_int32' => [-62 => -62], + 'map_int64_int64' => [-63 => -63], + 'map_uint32_uint32' => [62 => 62], + 'map_uint64_uint64' => [63 => 63], + 'map_sint32_sint32' => [-64 => -64], + 'map_sint64_sint64' => [-65 => -65], + 'map_fixed32_fixed32' => [66 => 66], + 'map_fixed64_fixed64' => [67 => 67], + 'map_sfixed32_sfixed32' => [-68 => -68], + 'map_sfixed64_sfixed64' => [-69 => -69], + 'map_int32_float' => [1 => 3.5], + 'map_int32_double' => [1 => 3.6], + 'map_bool_bool' => [true => true], + 'map_string_string' => ['e' => 'e'], + 'map_int32_bytes' => [1 => 'f'], + 'map_int32_enum' => [1 => TestEnum::ONE], + 'map_int32_message' => [1 => new TestMessage_Sub(['a' => 36])], + ]); + + TestUtil::assertTestMessage($m); + } } diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php index 720af1323c..6481473e45 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/php_implementation_test.php @@ -514,87 +514,6 @@ class ImplementationTest extends TestBase $this->assertSame(166, $m->byteSize()); } - public function testArrayConstructor() - { - $m = new TestMessage([ - 'optional_int32' => -42, - 'optional_int64' => -43, - 'optional_uint32' => 42, - 'optional_uint64' => 43, - 'optional_sint32' => -44, - 'optional_sint64' => -45, - 'optional_fixed32' => 46, - 'optional_fixed64' => 47, - 'optional_sfixed32' => -46, - 'optional_sfixed64' => -47, - 'optional_float' => 1.5, - 'optional_double' => 1.6, - 'optional_bool' => true, - 'optional_string' => 'a', - 'optional_bytes' => 'b', - 'optional_enum' => TestEnum::ONE, - 'optional_message' => new TestMessage_Sub([ - 'a' => 33 - ]), - 'repeated_int32' => [-42, -52], - 'repeated_int64' => [-43, -53], - 'repeated_uint32' => [42, 52], - 'repeated_uint64' => [43, 53], - 'repeated_sint32' => [-44, -54], - 'repeated_sint64' => [-45, -55], - 'repeated_fixed32' => [46, 56], - 'repeated_fixed64' => [47, 57], - 'repeated_sfixed32' => [-46, -56], - 'repeated_sfixed64' => [-47, -57], - 'repeated_float' => [1.5, 2.5], - 'repeated_double' => [1.6, 2.6], - 'repeated_bool' => [true, false], - 'repeated_string' => ['a', 'c'], - 'repeated_bytes' => ['b', 'd'], - 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], - 'repeated_message' => [ - new TestMessage_Sub(['a' => 34]), - new TestMessage_Sub(['a' => 35]), - ], - 'map_int32_int32' => [-62 => -62], - 'map_int64_int64' => [-63 => -63], - 'map_uint32_uint32' => [62 => 62], - 'map_uint64_uint64' => [63 => 63], - 'map_sint32_sint32' => [-64 => -64], - 'map_sint64_sint64' => [-65 => -65], - 'map_fixed32_fixed32' => [66 => 66], - 'map_fixed64_fixed64' => [67 => 67], - 'map_sfixed32_sfixed32' => [-68 => -68], - 'map_sfixed64_sfixed64' => [-69 => -69], - 'map_int32_float' => [1 => 3.5], - 'map_int32_double' => [1 => 3.6], - 'map_bool_bool' => [true => true], - 'map_string_string' => ['e' => 'e'], - 'map_int32_bytes' => [1 => 'f'], - 'map_int32_enum' => [1 => TestEnum::ONE], - 'map_int32_message' => [1 => new TestMessage_Sub(['a' => 36])], - ]); - - TestUtil::assertTestMessage($m); - - // Using message objects - $m = new TestMessage([ - 'optional_message' => new TestMessage_Sub(['a' => 33]), - 'repeated_message' => [ - new TestMessage_Sub(['a' => 34]), - new TestMessage_Sub(['a' => 35]), - ], - 'map_int32_message' => [ - 1 => new TestMessage_Sub(['a' => 36]) - ], - ]); - - $this->assertEquals(33, $m->getOptionalMessage()->getA()); - $this->assertEquals(34, $m->getRepeatedMessage()[0]->getA()); - $this->assertEquals(35, $m->getRepeatedMessage()[1]->getA()); - $this->assertEquals(36, $m->getMapInt32Message()[1]->getA()); - } - /** * @expectedException UnexpectedValueException * @expectedExceptionMessage Invalid message property: optionalInt32 From 2774e5441d8508b7d61cc3786b69149dc43d9f42 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 23 May 2018 16:43:30 -0700 Subject: [PATCH 09/28] PHP namespaces for nested messages and enums (#4536) * uses namespaces for nested messages and enums * fixes namespaces for PHP dist * fixes namespace for Descriptors, adds Cardinality and Kind * fixes nested namespaces for reserved words and adds tests * adds tests and generator fix for php class prefixes * fixes escaping of protobuf packages, enum comments, misc others * nice refactor of generated code * adds class files for backwards compatibility * simplifies code with templates * adds compatibility files to makefile * cleanup of generator and fixes nested namespace bug * regenerates proto types * remove internal BC classes * adds deprecated warning, adds methods back * simplifies if statement * fixes dist files * addresses review comments * adds back TYPE_URL_PREFIX constant * adds @deprecated to old nested class files * skips tests which require a separate process when protobuf.so is enabled * Adds tests for legacy nested classes that do not require separate processes to test * uses legacy names for GPBUtil message check * adds block for IDE @deprecated message * Namespace for nested message/enum in c extension * Remove unused code --- Makefile.am | 28 +- php/ext/google/protobuf/def.c | 253 +++++++++----- php/ext/google/protobuf/message.c | 8 +- .../Google/Protobuf/Internal/Descriptor.php | 12 +- php/src/Google/Protobuf/Any.php | 108 ++++-- php/src/Google/Protobuf/Api.php | 44 ++- php/src/Google/Protobuf/BoolValue.php | 14 +- php/src/Google/Protobuf/BytesValue.php | 14 +- php/src/Google/Protobuf/DoubleValue.php | 14 +- php/src/Google/Protobuf/Duration.php | 24 +- php/src/Google/Protobuf/Enum.php | 22 +- php/src/Google/Protobuf/EnumValue.php | 18 +- php/src/Google/Protobuf/Field.php | 34 +- php/src/Google/Protobuf/Field/Cardinality.php | 42 +++ php/src/Google/Protobuf/Field/Kind.php | 132 +++++++ php/src/Google/Protobuf/FieldMask.php | 18 +- php/src/Google/Protobuf/Field_Cardinality.php | 35 +- php/src/Google/Protobuf/Field_Kind.php | 125 +------ php/src/Google/Protobuf/FloatValue.php | 14 +- php/src/Google/Protobuf/GPBEmpty.php | 12 +- php/src/Google/Protobuf/Int32Value.php | 14 +- php/src/Google/Protobuf/Int64Value.php | 14 +- .../Protobuf/Internal/DescriptorProto.php | 12 +- .../ExtensionRange.php} | 7 +- .../ReservedRange.php} | 7 +- .../Protobuf/Internal/EnumDescriptorProto.php | 6 +- .../EnumReservedRange.php} | 7 +- .../Label.php} | 9 +- .../Type.php} | 9 +- .../CType.php} | 9 +- .../JSType.php} | 9 +- .../Google/Protobuf/Internal/FileOptions.php | 8 + .../OptimizeMode.php} | 9 +- php/src/Google/Protobuf/Internal/GPBUtil.php | 18 +- .../Protobuf/Internal/GeneratedCodeInfo.php | 6 +- .../Annotation.php} | 7 +- .../IdempotencyLevel.php} | 9 +- .../Protobuf/Internal/SourceCodeInfo.php | 6 +- .../Location.php} | 7 +- .../Protobuf/Internal/UninterpretedOption.php | 6 +- .../NamePart.php} | 7 +- php/src/Google/Protobuf/ListValue.php | 14 +- php/src/Google/Protobuf/Method.php | 26 +- php/src/Google/Protobuf/Mixin.php | 17 +- php/src/Google/Protobuf/NullValue.php | 2 +- php/src/Google/Protobuf/Option.php | 22 +- php/src/Google/Protobuf/SourceContext.php | 15 +- php/src/Google/Protobuf/StringValue.php | 14 +- php/src/Google/Protobuf/Struct.php | 14 +- php/src/Google/Protobuf/Syntax.php | 2 +- php/src/Google/Protobuf/Timestamp.php | 23 +- php/src/Google/Protobuf/Type.php | 24 +- php/src/Google/Protobuf/UInt32Value.php | 14 +- php/src/Google/Protobuf/UInt64Value.php | 14 +- php/src/Google/Protobuf/Value.php | 24 +- php/tests/array_test.php | 12 +- php/tests/descriptors_test.php | 2 +- php/tests/encode_decode_test.php | 6 +- php/tests/gdb_test.sh | 4 +- php/tests/generated_class_test.php | 165 +++++++-- php/tests/generated_phpdoc_test.php | 6 +- php/tests/map_field_test.php | 10 +- php/tests/memory_leak_test.php | 10 +- php/tests/php_implementation_test.php | 4 +- php/tests/proto/empty/echo.proto | 17 + .../proto/test_empty_php_namespace.proto | 10 + php/tests/proto/test_include.proto | 11 + php/tests/proto/test_no_namespace.proto | 12 +- php/tests/proto/test_php_namespace.proto | 22 ++ php/tests/proto/test_prefix.proto | 8 + php/tests/test_base.php | 2 +- php/tests/test_util.php | 18 +- php/tests/undefined_test.php | 86 ++--- php/tests/well_known_test.php | 12 +- .../protobuf/compiler/php/php_generator.cc | 322 ++++++++++-------- .../protobuf/compiler/php/php_generator.h | 10 - tests.sh | 3 +- 77 files changed, 1477 insertions(+), 657 deletions(-) create mode 100644 php/src/Google/Protobuf/Field/Cardinality.php create mode 100644 php/src/Google/Protobuf/Field/Kind.php rename php/src/Google/Protobuf/Internal/{DescriptorProto_ExtensionRange.php => DescriptorProto/ExtensionRange.php} (91%) rename php/src/Google/Protobuf/Internal/{DescriptorProto_ReservedRange.php => DescriptorProto/ReservedRange.php} (89%) rename php/src/Google/Protobuf/Internal/{EnumDescriptorProto_EnumReservedRange.php => EnumDescriptorProto/EnumReservedRange.php} (89%) rename php/src/Google/Protobuf/Internal/{FieldDescriptorProto_Label.php => FieldDescriptorProto/Label.php} (61%) rename php/src/Google/Protobuf/Internal/{FieldDescriptorProto_Type.php => FieldDescriptorProto/Type.php} (90%) rename php/src/Google/Protobuf/Internal/{FieldOptions_CType.php => FieldOptions/CType.php} (61%) rename php/src/Google/Protobuf/Internal/{FieldOptions_JSType.php => FieldOptions/JSType.php} (65%) rename php/src/Google/Protobuf/Internal/{FileOptions_OptimizeMode.php => FileOptions/OptimizeMode.php} (67%) rename php/src/Google/Protobuf/Internal/{GeneratedCodeInfo_Annotation.php => GeneratedCodeInfo/Annotation.php} (95%) rename php/src/Google/Protobuf/Internal/{MethodOptions_IdempotencyLevel.php => MethodOptions/IdempotencyLevel.php} (70%) rename php/src/Google/Protobuf/Internal/{SourceCodeInfo_Location.php => SourceCodeInfo/Location.php} (98%) rename php/src/Google/Protobuf/Internal/{UninterpretedOption_NamePart.php => UninterpretedOption/NamePart.php} (90%) create mode 100644 php/tests/proto/empty/echo.proto diff --git a/Makefile.am b/Makefile.am index 971e46ee75..ae4ac858cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -619,7 +619,9 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Field.php \ php/src/Google/Protobuf/FieldDescriptor.php \ php/src/Google/Protobuf/FieldMask.php \ + php/src/Google/Protobuf/Field/Cardinality.php \ php/src/Google/Protobuf/Field_Cardinality.php \ + php/src/Google/Protobuf/Field/Kind.php \ php/src/Google/Protobuf/Field_Kind.php \ php/src/Google/Protobuf/FloatValue.php \ php/src/Google/Protobuf/GPBEmpty.php \ @@ -630,30 +632,29 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Internal/Descriptor.php \ php/src/Google/Protobuf/Internal/DescriptorPool.php \ php/src/Google/Protobuf/Internal/DescriptorProto.php \ - php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php \ - php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php \ + php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php \ + php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php \ php/src/Google/Protobuf/Internal/EnumBuilderContext.php \ php/src/Google/Protobuf/Internal/EnumDescriptor.php \ php/src/Google/Protobuf/Internal/EnumDescriptorProto.php \ - php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php \ + php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php \ php/src/Google/Protobuf/Internal/EnumOptions.php \ php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php \ php/src/Google/Protobuf/Internal/EnumValueOptions.php \ php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php \ - php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php \ php/src/Google/Protobuf/Internal/FieldDescriptorProto.php \ php/src/Google/Protobuf/Internal/FieldDescriptor.php \ php/src/Google/Protobuf/Internal/FieldDescriptorProto.php \ - php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php \ - php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php \ + php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php \ + php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php \ php/src/Google/Protobuf/Internal/FieldOptions.php \ - php/src/Google/Protobuf/Internal/FieldOptions_CType.php \ - php/src/Google/Protobuf/Internal/FieldOptions_JSType.php \ + php/src/Google/Protobuf/Internal/FieldOptions/CType.php \ + php/src/Google/Protobuf/Internal/FieldOptions/JSType.php \ php/src/Google/Protobuf/Internal/FileDescriptor.php \ php/src/Google/Protobuf/Internal/FileDescriptorProto.php \ php/src/Google/Protobuf/Internal/FileDescriptorSet.php \ php/src/Google/Protobuf/Internal/FileOptions.php \ - php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php \ + php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php \ php/src/Google/Protobuf/Internal/GPBDecodeException.php \ php/src/Google/Protobuf/Internal/GPBJsonWire.php \ php/src/Google/Protobuf/Internal/GPBLabel.php \ @@ -662,7 +663,7 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Internal/GPBWire.php \ php/src/Google/Protobuf/Internal/GPBWireType.php \ php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php \ - php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php \ + php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php \ php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php \ php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php \ php/src/Google/Protobuf/Internal/MapEntry.php \ @@ -673,7 +674,7 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Internal/MessageOptions.php \ php/src/Google/Protobuf/Internal/MethodDescriptorProto.php \ php/src/Google/Protobuf/Internal/MethodOptions.php \ - php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php \ + php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php \ php/src/Google/Protobuf/Internal/OneofDescriptor.php \ php/src/Google/Protobuf/Internal/OneofDescriptorProto.php \ php/src/Google/Protobuf/Internal/OneofField.php \ @@ -684,9 +685,9 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php \ php/src/Google/Protobuf/Internal/ServiceOptions.php \ php/src/Google/Protobuf/Internal/SourceCodeInfo.php \ - php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php \ + php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php \ php/src/Google/Protobuf/Internal/UninterpretedOption.php \ - php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php \ + php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php \ php/src/Google/Protobuf/ListValue.php \ php/src/Google/Protobuf/Method.php \ php/src/Google/Protobuf/Mixin.php \ @@ -716,6 +717,7 @@ php_EXTRA_DIST= \ php/tests/map_field_test.php \ php/tests/memory_leak_test.php \ php/tests/php_implementation_test.php \ + php/tests/proto/empty/echo.proto \ php/tests/proto/test.proto \ php/tests/proto/test_descriptors.proto \ php/tests/proto/test_empty_php_namespace.proto \ diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 8140fe4751..cb2c72019f 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -718,105 +718,186 @@ PHP_METHOD(InternalDescriptorPool, getGeneratedPool) { #endif } -static void classname_no_prefix(const char *fullname, const char *package_name, - char *class_name) { - size_t i = 0, j; - bool first_char = true, is_reserved = false; - size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name); - size_t message_name_start = package_name == NULL ? 0 : pkg_name_len + 1; - size_t message_len = (strlen(fullname) - message_name_start); +static size_t classname_len_max(const char *fullname, + const char *package, + const char *php_namespace, + const char *prefix) { + size_t fullname_len = strlen(fullname); + size_t package_len = 0; + size_t prefix_len = 0; + size_t namespace_len = 0; + size_t length = fullname_len; + int i, segment, classname_start = 0; + + if (package != NULL) { + package_len = strlen(package); + } + if (prefix != NULL) { + prefix_len = strlen(prefix); + } + if (php_namespace != NULL) { + namespace_len = strlen(php_namespace); + } - // Submessage is concatenated with its containing messages by '_'. - for (j = message_name_start; j < message_name_start + message_len; j++) { - if (fullname[j] == '.') { - class_name[i++] = '_'; - } else { - class_name[i++] = fullname[j]; + // Process package + if (package_len > 0) { + segment = 1; + for (i = 0; i < package_len; i++) { + if (package[i] == '.') { + segment++; + } } - } -} + // In case of reserved name in package. + length += 3 * segment; -static const char *classname_prefix(const char *classname, - const char *prefix_given, - const char *package_name) { - size_t i; - bool is_reserved = false; + classname_start = package_len + 1; + } - if (prefix_given != NULL && strcmp(prefix_given, "") != 0) { - return prefix_given; + // Process class name + segment = 1; + for (i = classname_start; i < fullname_len; i++) { + if (fullname[i] == '.') { + segment++; + } + } + if (prefix_len == 0) { + length += 3 * segment; + } else { + length += prefix_len * segment; } - char* lower = ALLOC_N(char, strlen(classname) + 1); - i = 0; - while(classname[i]) { - lower[i] = (char)tolower(classname[i]); + // The additional 2, one is for preceding '.' and the other is for trailing 0. + return length + namespace_len + 2; +} + +static bool is_reserved(const char *segment, int length) { + bool result; + char* lower = ALLOC_N(char, length + 1); + memcpy(lower, segment, length); + int i = 0; + while(lower[i]) { + lower[i] = (char)tolower(lower[i]); i++; } - lower[i] = 0; - - is_reserved = is_reserved_name(lower); + lower[length] = 0; + result = is_reserved_name(lower); FREE(lower); + return result; +} - if (is_reserved) { - if (package_name != NULL && strcmp("google.protobuf", package_name) == 0) { - return "GPB"; - } else { - return "PB"; +static char* fill_prefix(const char *segment, int length, + const char *prefix_given, + const char *package_name, char *classname) { + size_t i; + + if (prefix_given != NULL && strcmp(prefix_given, "") != 0) { + size_t prefix_len = strlen(prefix_given); + memcpy(classname, prefix_given, strlen(prefix_given)); + classname += prefix_len; + } else { + if (is_reserved(segment, length)) { + if (package_name != NULL && + strcmp("google.protobuf", package_name) == 0) { + memcpy(classname, "GPB", 3); + classname += 3; + } else { + memcpy(classname, "PB", 2); + classname += 2; + } } } + return classname; +} - return ""; +static char* fill_segment(const char *segment, int length, + char *classname, bool use_camel) { + memcpy(classname, segment, length); + if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) { + classname[0] += 'A' - 'a'; + } + return classname + length; } -static void convert_to_class_name_inplace(const char *package, - const char *namespace_given, - const char *prefix, char *classname) { - size_t prefix_len = prefix == NULL ? 0 : strlen(prefix); - size_t classname_len = strlen(classname); - int i = 0, j; - bool first_char = true; +static char* fill_namespace(const char *package, const char *namespace_given, + char *classname) { + if (namespace_given != NULL) { + size_t namespace_len = strlen(namespace_given); + memcpy(classname, namespace_given, namespace_len); + classname += namespace_len; + *classname = '\\'; + classname++; + } else if (package != NULL) { + int i = 0, j, offset = 0; + size_t package_len = strlen(package); + while (i < package_len) { + j = i; + while (j < package_len && package[j] != '.') { + j++; + } + classname = fill_prefix(package + i, j - i, "", package, classname); + classname = fill_segment(package + i, j - i, classname, true); + classname[0] = '\\'; + classname++; + i = j + 1; + } + } + return classname; +} - size_t package_len = package == NULL ? 0 : strlen(package); - size_t namespace_given_len = - namespace_given == NULL ? 0 : strlen(namespace_given); - bool use_namespace_given = namespace_given != NULL; - size_t namespace_len = - use_namespace_given ? namespace_given_len : package_len; +static char* fill_classname(const char *fullname, + const char *package, + const char *namespace_given, + const char *prefix, char *classname) { + int classname_start = 0; + if (package != NULL) { + size_t package_len = strlen(package); + classname_start = package_len == 0 ? 0 : package_len + 1; + } + size_t fullname_len = strlen(fullname); + classname = fill_prefix(fullname + classname_start, + fullname_len - classname_start, + prefix, package, classname); + + int i = classname_start, j; + while (i < fullname_len) { + j = i; + while (j < fullname_len && fullname[j] != '.') { + j++; + } + classname = fill_segment(fullname + i, j - i, classname, false); + if (j != fullname_len) { + *classname = '_'; + classname++; + } + i = j + 1; + } + return classname; +} - int offset = namespace_len != 0 ? 2 : 0; +static char* fill_qualified_classname(const char *fullname, + const char *package, + const char *namespace_given, + const char *prefix, char *classname) { + classname = fill_namespace(package, namespace_given, classname); + return fill_classname(fullname, package, namespace_given, prefix, classname); +} - for (j = 0; j < classname_len; j++) { - classname[namespace_len + prefix_len + classname_len + offset - 1 - j] = - classname[classname_len - j - 1]; - } +static void classname_no_prefix(const char *fullname, const char *package_name, + char *class_name) { + size_t i = 0, j; + bool first_char = true, is_reserved = false; + size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name); + size_t message_name_start = package_name == NULL ? 0 : pkg_name_len + 1; + size_t message_len = (strlen(fullname) - message_name_start); - if (namespace_len != 0) { - classname[i++] = '\\'; - for (j = 0; j < namespace_len; j++) { - if (use_namespace_given) { - classname[i++] = namespace_given[j]; - continue; - } - // php packages are divided by '\'. - if (package[j] == '.') { - classname[i++] = '\\'; - first_char = true; - } else if (first_char) { - // PHP package uses camel case. - if (package[j] < 'A' || package[j] > 'Z') { - classname[i++] = package[j] + 'A' - 'a'; - } else { - classname[i++] = package[j]; - } - first_char = false; - } else { - classname[i++] = package[j]; - } + // Submessage is concatenated with its containing messages by '_'. + for (j = message_name_start; j < message_name_start + message_len; j++) { + if (fullname[j] == '.') { + class_name[i++] = '_'; + } else { + class_name[i++] = fullname[j]; } - classname[i++] = '\\'; } - - memcpy(classname + i, prefix, prefix_len); } void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len, @@ -858,20 +939,14 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len, * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \ * given message is google.protobuf.Empty.*/ \ const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \ + const char *package = upb_filedef_package(files[0]); \ const char *php_namespace = upb_filedef_phpnamespace(files[0]); \ const char *prefix_given = upb_filedef_phpprefix(files[0]); \ - size_t classname_len = strlen(fullname) + 5; \ - if (prefix_given != NULL) { \ - classname_len += strlen(prefix_given); \ - } \ - if (php_namespace != NULL) { \ - classname_len += strlen(php_namespace); \ - } \ + size_t classname_len = classname_len_max(fullname, package, \ + php_namespace, prefix_given); \ char *classname = ecalloc(sizeof(char), classname_len); \ - const char *package = upb_filedef_package(files[0]); \ - classname_no_prefix(fullname, package, classname); \ - const char *prefix = classname_prefix(classname, prefix_given, package); \ - convert_to_class_name_inplace(package, php_namespace, prefix, classname); \ + fill_qualified_classname(fullname, package, php_namespace, \ + prefix_given, classname); \ PHP_PROTO_CE_DECLARE pce; \ if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) == \ FAILURE) { \ diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 5a8734bc32..690128719f 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -858,7 +858,7 @@ static zend_function_entry field_cardinality_methods[] = { zend_class_entry* field_cardinality_type; // Init class entry. -PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Cardinality", +PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Cardinality", Field_Cardinality, field_cardinality) zend_declare_class_constant_long(field_cardinality_type, "CARDINALITY_UNKNOWN", 19, 0 TSRMLS_CC); @@ -868,6 +868,8 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Cardinality", "CARDINALITY_REQUIRED", 20, 2 TSRMLS_CC); zend_declare_class_constant_long(field_cardinality_type, "CARDINALITY_REPEATED", 20, 3 TSRMLS_CC); + const char *alias = "Google\\Protobuf\\Field_Cardinality"; + zend_register_class_alias_ex(alias, strlen(alias), field_cardinality_type TSRMLS_CC); PHP_PROTO_INIT_ENUMCLASS_END // ----------------------------------------------------------------------------- @@ -881,7 +883,7 @@ static zend_function_entry field_kind_methods[] = { zend_class_entry* field_kind_type; // Init class entry. -PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Kind", +PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Kind", Field_Kind, field_kind) zend_declare_class_constant_long(field_kind_type, "TYPE_UNKNOWN", 12, 0 TSRMLS_CC); @@ -921,6 +923,8 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Kind", "TYPE_SINT32", 11, 17 TSRMLS_CC); zend_declare_class_constant_long(field_kind_type, "TYPE_SINT64", 11, 18 TSRMLS_CC); + const char *alias = "Google\\Protobuf\\Field_Kind"; + zend_register_class_alias_ex(alias, strlen(alias), field_kind_type TSRMLS_CC); PHP_PROTO_INIT_ENUMCLASS_END // ----------------------------------------------------------------------------- diff --git a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php index 7057384bb8..e6362f2bfb 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php @@ -46,13 +46,13 @@ class Descriptor ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 10) ->finalizeToPool(); - $pool->addMessage('google.protobuf.internal.DescriptorProto.ExtensionRange', \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class) + $pool->addMessage('google.protobuf.internal.DescriptorProto.ExtensionRange', \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class) ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.ExtensionRangeOptions') ->finalizeToPool(); - $pool->addMessage('google.protobuf.internal.DescriptorProto.ReservedRange', \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class) + $pool->addMessage('google.protobuf.internal.DescriptorProto.ReservedRange', \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class) ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) ->finalizeToPool(); @@ -114,7 +114,7 @@ class Descriptor ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 5) ->finalizeToPool(); - $pool->addMessage('google.protobuf.internal.EnumDescriptorProto.EnumReservedRange', \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange::class) + $pool->addMessage('google.protobuf.internal.EnumDescriptorProto.EnumReservedRange', \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class) ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) ->finalizeToPool(); @@ -242,7 +242,7 @@ class Descriptor ->optional('aggregate_value', \Google\Protobuf\Internal\GPBType::STRING, 8) ->finalizeToPool(); - $pool->addMessage('google.protobuf.internal.UninterpretedOption.NamePart', \Google\Protobuf\Internal\UninterpretedOption_NamePart::class) + $pool->addMessage('google.protobuf.internal.UninterpretedOption.NamePart', \Google\Protobuf\Internal\UninterpretedOption\NamePart::class) ->required('name_part', \Google\Protobuf\Internal\GPBType::STRING, 1) ->required('is_extension', \Google\Protobuf\Internal\GPBType::BOOL, 2) ->finalizeToPool(); @@ -251,7 +251,7 @@ class Descriptor ->repeated('location', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.SourceCodeInfo.Location') ->finalizeToPool(); - $pool->addMessage('google.protobuf.internal.SourceCodeInfo.Location', \Google\Protobuf\Internal\SourceCodeInfo_Location::class) + $pool->addMessage('google.protobuf.internal.SourceCodeInfo.Location', \Google\Protobuf\Internal\SourceCodeInfo\Location::class) ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1) ->repeated('span', \Google\Protobuf\Internal\GPBType::INT32, 2) ->optional('leading_comments', \Google\Protobuf\Internal\GPBType::STRING, 3) @@ -263,7 +263,7 @@ class Descriptor ->repeated('annotation', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.GeneratedCodeInfo.Annotation') ->finalizeToPool(); - $pool->addMessage('google.protobuf.internal.GeneratedCodeInfo.Annotation', \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class) + $pool->addMessage('google.protobuf.internal.GeneratedCodeInfo.Annotation', \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class) ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('source_file', \Google\Protobuf\Internal\GPBType::STRING, 2) ->optional('begin', \Google\Protobuf\Internal\GPBType::INT32, 3) diff --git a/php/src/Google/Protobuf/Any.php b/php/src/Google/Protobuf/Any.php index f027b05d2e..a992854957 100644 --- a/php/src/Google/Protobuf/Any.php +++ b/php/src/Google/Protobuf/Any.php @@ -5,9 +5,9 @@ namespace Google\Protobuf; use Google\Protobuf\Internal\GPBType; -use Google\Protobuf\Internal\GPBUtil; use Google\Protobuf\Internal\Message; use Google\Protobuf\Internal\RepeatedField; +use Google\Protobuf\Internal\GPBUtil; /** * `Any` contains an arbitrary serialized protocol buffer message along with a @@ -37,6 +37,14 @@ use Google\Protobuf\Internal\RepeatedField; * if any.Is(Foo.DESCRIPTOR): * any.Unpack(foo) * ... + * Example 4: Pack and unpack a message in Go + * foo := &pb.Foo{...} + * any, err := ptypes.MarshalAny(foo) + * ... + * foo := &pb.Foo{} + * if err := ptypes.UnmarshalAny(any, foo); err != nil { + * ... + * } * The pack methods provided by protobuf library will by default use * 'type.googleapis.com/full.type.name' as the type URL and the unpack * methods only use the fully qualified type name after the last '/' @@ -71,15 +79,16 @@ use Google\Protobuf\Internal\RepeatedField; class Any extends \Google\Protobuf\Internal\Message { /** - * A URL/resource name whose content describes the type of the - * serialized protocol buffer message. - * For URLs which use the scheme `http`, `https`, or no scheme, the - * following restrictions and interpretations apply: + * A URL/resource name that uniquely identifies the type of the serialized + * protocol buffer message. The last segment of the URL's path must represent + * the fully qualified name of the type (as in + * `path/google.protobuf.Duration`). The name should be in a canonical form + * (e.g., leading "." is not accepted). + * In practice, teams usually precompile into the binary all types that they + * expect it to use in the context of Any. However, for URLs which use the + * scheme `http`, `https`, or no scheme, one can optionally set up a type + * server that maps type URLs to message definitions as follows: * * If no scheme is provided, `https` is assumed. - * * The last segment of the URL's path must represent the fully - * qualified name of the type (as in `path/google.protobuf.Duration`). - * The name should be in a canonical form (e.g., leading "." is - * not accepted). * * An HTTP GET on the URL must yield a [google.protobuf.Type][] * value in binary format, or produce an error. * * Applications are allowed to cache lookup results based on the @@ -87,6 +96,9 @@ class Any extends \Google\Protobuf\Internal\Message * lookup. Therefore, binary compatibility needs to be preserved * on changes to types. (Use versioned type names to manage * breaking changes.) + * Note: this functionality is not currently available in the official + * protobuf release, and it is not used for type URLs beginning with + * type.googleapis.com. * Schemes other than `http`, `https` (or the empty scheme) might be * used with implementation specific semantics. * @@ -102,21 +114,55 @@ class Any extends \Google\Protobuf\Internal\Message const TYPE_URL_PREFIX = 'type.googleapis.com/'; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $type_url + * A URL/resource name that uniquely identifies the type of the serialized + * protocol buffer message. The last segment of the URL's path must represent + * the fully qualified name of the type (as in + * `path/google.protobuf.Duration`). The name should be in a canonical form + * (e.g., leading "." is not accepted). + * In practice, teams usually precompile into the binary all types that they + * expect it to use in the context of Any. However, for URLs which use the + * scheme `http`, `https`, or no scheme, one can optionally set up a type + * server that maps type URLs to message definitions as follows: + * * If no scheme is provided, `https` is assumed. + * * An HTTP GET on the URL must yield a [google.protobuf.Type][] + * value in binary format, or produce an error. + * * Applications are allowed to cache lookup results based on the + * URL, or have them precompiled into a binary to avoid any + * lookup. Therefore, binary compatibility needs to be preserved + * on changes to types. (Use versioned type names to manage + * breaking changes.) + * Note: this functionality is not currently available in the official + * protobuf release, and it is not used for type URLs beginning with + * type.googleapis.com. + * Schemes other than `http`, `https` (or the empty scheme) might be + * used with implementation specific semantics. + * @type string $value + * Must be a valid serialized protocol buffer of the above specified type. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Any::initOnce(); - parent::__construct(); + parent::__construct($data); } /** - * A URL/resource name whose content describes the type of the - * serialized protocol buffer message. - * For URLs which use the scheme `http`, `https`, or no scheme, the - * following restrictions and interpretations apply: + * A URL/resource name that uniquely identifies the type of the serialized + * protocol buffer message. The last segment of the URL's path must represent + * the fully qualified name of the type (as in + * `path/google.protobuf.Duration`). The name should be in a canonical form + * (e.g., leading "." is not accepted). + * In practice, teams usually precompile into the binary all types that they + * expect it to use in the context of Any. However, for URLs which use the + * scheme `http`, `https`, or no scheme, one can optionally set up a type + * server that maps type URLs to message definitions as follows: * * If no scheme is provided, `https` is assumed. - * * The last segment of the URL's path must represent the fully - * qualified name of the type (as in `path/google.protobuf.Duration`). - * The name should be in a canonical form (e.g., leading "." is - * not accepted). * * An HTTP GET on the URL must yield a [google.protobuf.Type][] * value in binary format, or produce an error. * * Applications are allowed to cache lookup results based on the @@ -124,6 +170,9 @@ class Any extends \Google\Protobuf\Internal\Message * lookup. Therefore, binary compatibility needs to be preserved * on changes to types. (Use versioned type names to manage * breaking changes.) + * Note: this functionality is not currently available in the official + * protobuf release, and it is not used for type URLs beginning with + * type.googleapis.com. * Schemes other than `http`, `https` (or the empty scheme) might be * used with implementation specific semantics. * @@ -136,15 +185,16 @@ class Any extends \Google\Protobuf\Internal\Message } /** - * A URL/resource name whose content describes the type of the - * serialized protocol buffer message. - * For URLs which use the scheme `http`, `https`, or no scheme, the - * following restrictions and interpretations apply: + * A URL/resource name that uniquely identifies the type of the serialized + * protocol buffer message. The last segment of the URL's path must represent + * the fully qualified name of the type (as in + * `path/google.protobuf.Duration`). The name should be in a canonical form + * (e.g., leading "." is not accepted). + * In practice, teams usually precompile into the binary all types that they + * expect it to use in the context of Any. However, for URLs which use the + * scheme `http`, `https`, or no scheme, one can optionally set up a type + * server that maps type URLs to message definitions as follows: * * If no scheme is provided, `https` is assumed. - * * The last segment of the URL's path must represent the fully - * qualified name of the type (as in `path/google.protobuf.Duration`). - * The name should be in a canonical form (e.g., leading "." is - * not accepted). * * An HTTP GET on the URL must yield a [google.protobuf.Type][] * value in binary format, or produce an error. * * Applications are allowed to cache lookup results based on the @@ -152,6 +202,9 @@ class Any extends \Google\Protobuf\Internal\Message * lookup. Therefore, binary compatibility needs to be preserved * on changes to types. (Use versioned type names to manage * breaking changes.) + * Note: this functionality is not currently available in the official + * protobuf release, and it is not used for type URLs beginning with + * type.googleapis.com. * Schemes other than `http`, `https` (or the empty scheme) might be * used with implementation specific semantics. * @@ -269,3 +322,4 @@ class Any extends \Google\Protobuf\Internal\Message return $this->type_url === $type_url; } } + diff --git a/php/src/Google/Protobuf/Api.php b/php/src/Google/Protobuf/Api.php index d0dda3cd70..db37ffb019 100644 --- a/php/src/Google/Protobuf/Api.php +++ b/php/src/Google/Protobuf/Api.php @@ -83,9 +83,49 @@ class Api extends \Google\Protobuf\Internal\Message */ private $syntax = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * The fully qualified name of this interface, including package name + * followed by the interface's simple name. + * @type \Google\Protobuf\Method[]|\Google\Protobuf\Internal\RepeatedField $methods + * The methods of this interface, in unspecified order. + * @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options + * Any metadata attached to the interface. + * @type string $version + * A version string for this interface. If specified, must have the form + * `major-version.minor-version`, as in `1.10`. If the minor version is + * omitted, it defaults to zero. If the entire version field is empty, the + * major version is derived from the package name, as outlined below. If the + * field is not empty, the version in the package name will be verified to be + * consistent with what is provided here. + * The versioning schema uses [semantic + * versioning](http://semver.org) where the major version number + * indicates a breaking change and the minor version an additive, + * non-breaking change. Both version numbers are signals to users + * what to expect from different versions, and should be carefully + * chosen based on the product plan. + * The major version is also reflected in the package name of the + * interface, which must end in `v`, as in + * `google.feature.v1`. For major versions 0 and 1, the suffix can + * be omitted. Zero major versions must only be used for + * experimental, non-GA interfaces. + * @type \Google\Protobuf\SourceContext $source_context + * Source context for the protocol buffer service represented by this + * message. + * @type \Google\Protobuf\Mixin[]|\Google\Protobuf\Internal\RepeatedField $mixins + * Included interfaces. See [Mixin][]. + * @type int $syntax + * The source syntax of the service. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Api::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/BoolValue.php b/php/src/Google/Protobuf/BoolValue.php index c28bf94106..13872eb1e4 100644 --- a/php/src/Google/Protobuf/BoolValue.php +++ b/php/src/Google/Protobuf/BoolValue.php @@ -23,9 +23,19 @@ class BoolValue extends \Google\Protobuf\Internal\Message */ private $value = false; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type bool $value + * The bool value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/BytesValue.php b/php/src/Google/Protobuf/BytesValue.php index d6a6b2e634..f1b3817185 100644 --- a/php/src/Google/Protobuf/BytesValue.php +++ b/php/src/Google/Protobuf/BytesValue.php @@ -23,9 +23,19 @@ class BytesValue extends \Google\Protobuf\Internal\Message */ private $value = ''; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $value + * The bytes value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/DoubleValue.php b/php/src/Google/Protobuf/DoubleValue.php index 6718ce3cd7..236d918223 100644 --- a/php/src/Google/Protobuf/DoubleValue.php +++ b/php/src/Google/Protobuf/DoubleValue.php @@ -23,9 +23,19 @@ class DoubleValue extends \Google\Protobuf\Internal\Message */ private $value = 0.0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type float $value + * The double value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Duration.php b/php/src/Google/Protobuf/Duration.php index ca1c4c0777..414a1868b7 100644 --- a/php/src/Google/Protobuf/Duration.php +++ b/php/src/Google/Protobuf/Duration.php @@ -79,9 +79,28 @@ class Duration extends \Google\Protobuf\Internal\Message */ private $nanos = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int|string $seconds + * Signed seconds of the span of time. Must be from -315,576,000,000 + * to +315,576,000,000 inclusive. Note: these bounds are computed from: + * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + * @type int $nanos + * Signed fractions of a second at nanosecond resolution of the span + * of time. Durations less than one second are represented with a 0 + * `seconds` field and a positive or negative `nanos` field. For durations + * of one second or more, a non-zero value for the `nanos` field must be + * of the same sign as the `seconds` field. Must be from -999,999,999 + * to +999,999,999 inclusive. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Duration::initOnce(); - parent::__construct(); + parent::__construct($data); } /** @@ -149,5 +168,6 @@ class Duration extends \Google\Protobuf\Internal\Message return $this; } + } diff --git a/php/src/Google/Protobuf/Enum.php b/php/src/Google/Protobuf/Enum.php index c63efc74bf..243c40d289 100644 --- a/php/src/Google/Protobuf/Enum.php +++ b/php/src/Google/Protobuf/Enum.php @@ -46,9 +46,27 @@ class Enum extends \Google\Protobuf\Internal\Message */ private $syntax = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * Enum type name. + * @type \Google\Protobuf\EnumValue[]|\Google\Protobuf\Internal\RepeatedField $enumvalue + * Enum value definitions. + * @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options + * Protocol buffer options. + * @type \Google\Protobuf\SourceContext $source_context + * The source context. + * @type int $syntax + * The source syntax. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/EnumValue.php b/php/src/Google/Protobuf/EnumValue.php index e102c29f96..1dc3c7a6ee 100644 --- a/php/src/Google/Protobuf/EnumValue.php +++ b/php/src/Google/Protobuf/EnumValue.php @@ -34,9 +34,23 @@ class EnumValue extends \Google\Protobuf\Internal\Message */ private $options; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * Enum value name. + * @type int $number + * Enum value number. + * @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options + * Protocol buffer options. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Field.php b/php/src/Google/Protobuf/Field.php index 0b560d89e0..8da43e34da 100644 --- a/php/src/Google/Protobuf/Field.php +++ b/php/src/Google/Protobuf/Field.php @@ -78,9 +78,39 @@ class Field extends \Google\Protobuf\Internal\Message */ private $default_value = ''; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $kind + * The field type. + * @type int $cardinality + * The field cardinality. + * @type int $number + * The field number. + * @type string $name + * The field name. + * @type string $type_url + * The field type URL, without the scheme, for message or enumeration + * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + * @type int $oneof_index + * The index of the field type in `Type.oneofs`, for message or enumeration + * types. The first type has index 1; zero means the type is not in the list. + * @type bool $packed + * Whether to use alternative packed wire representation. + * @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options + * The protocol buffer options. + * @type string $json_name + * The field JSON name. + * @type string $default_value + * The string value of the default value of this field. Proto2 syntax only. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Field/Cardinality.php b/php/src/Google/Protobuf/Field/Cardinality.php new file mode 100644 index 0000000000..c887f6d31d --- /dev/null +++ b/php/src/Google/Protobuf/Field/Cardinality.php @@ -0,0 +1,42 @@ +google.protobuf.Field.Cardinality + */ +class Cardinality +{ + /** + * For fields with unknown cardinality. + * + * Generated from protobuf enum CARDINALITY_UNKNOWN = 0; + */ + const CARDINALITY_UNKNOWN = 0; + /** + * For optional fields. + * + * Generated from protobuf enum CARDINALITY_OPTIONAL = 1; + */ + const CARDINALITY_OPTIONAL = 1; + /** + * For required fields. Proto2 syntax only. + * + * Generated from protobuf enum CARDINALITY_REQUIRED = 2; + */ + const CARDINALITY_REQUIRED = 2; + /** + * For repeated fields. + * + * Generated from protobuf enum CARDINALITY_REPEATED = 3; + */ + const CARDINALITY_REPEATED = 3; +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Cardinality::class, \Google\Protobuf\Field_Cardinality::class); + diff --git a/php/src/Google/Protobuf/Field/Kind.php b/php/src/Google/Protobuf/Field/Kind.php new file mode 100644 index 0000000000..a2bbbdebbf --- /dev/null +++ b/php/src/Google/Protobuf/Field/Kind.php @@ -0,0 +1,132 @@ +google.protobuf.Field.Kind + */ +class Kind +{ + /** + * Field type unknown. + * + * Generated from protobuf enum TYPE_UNKNOWN = 0; + */ + const TYPE_UNKNOWN = 0; + /** + * Field type double. + * + * Generated from protobuf enum TYPE_DOUBLE = 1; + */ + const TYPE_DOUBLE = 1; + /** + * Field type float. + * + * Generated from protobuf enum TYPE_FLOAT = 2; + */ + const TYPE_FLOAT = 2; + /** + * Field type int64. + * + * Generated from protobuf enum TYPE_INT64 = 3; + */ + const TYPE_INT64 = 3; + /** + * Field type uint64. + * + * Generated from protobuf enum TYPE_UINT64 = 4; + */ + const TYPE_UINT64 = 4; + /** + * Field type int32. + * + * Generated from protobuf enum TYPE_INT32 = 5; + */ + const TYPE_INT32 = 5; + /** + * Field type fixed64. + * + * Generated from protobuf enum TYPE_FIXED64 = 6; + */ + const TYPE_FIXED64 = 6; + /** + * Field type fixed32. + * + * Generated from protobuf enum TYPE_FIXED32 = 7; + */ + const TYPE_FIXED32 = 7; + /** + * Field type bool. + * + * Generated from protobuf enum TYPE_BOOL = 8; + */ + const TYPE_BOOL = 8; + /** + * Field type string. + * + * Generated from protobuf enum TYPE_STRING = 9; + */ + const TYPE_STRING = 9; + /** + * Field type group. Proto2 syntax only, and deprecated. + * + * Generated from protobuf enum TYPE_GROUP = 10; + */ + const TYPE_GROUP = 10; + /** + * Field type message. + * + * Generated from protobuf enum TYPE_MESSAGE = 11; + */ + const TYPE_MESSAGE = 11; + /** + * Field type bytes. + * + * Generated from protobuf enum TYPE_BYTES = 12; + */ + const TYPE_BYTES = 12; + /** + * Field type uint32. + * + * Generated from protobuf enum TYPE_UINT32 = 13; + */ + const TYPE_UINT32 = 13; + /** + * Field type enum. + * + * Generated from protobuf enum TYPE_ENUM = 14; + */ + const TYPE_ENUM = 14; + /** + * Field type sfixed32. + * + * Generated from protobuf enum TYPE_SFIXED32 = 15; + */ + const TYPE_SFIXED32 = 15; + /** + * Field type sfixed64. + * + * Generated from protobuf enum TYPE_SFIXED64 = 16; + */ + const TYPE_SFIXED64 = 16; + /** + * Field type sint32. + * + * Generated from protobuf enum TYPE_SINT32 = 17; + */ + const TYPE_SINT32 = 17; + /** + * Field type sint64. + * + * Generated from protobuf enum TYPE_SINT64 = 18; + */ + const TYPE_SINT64 = 18; +} + +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Kind::class, \Google\Protobuf\Field_Kind::class); + diff --git a/php/src/Google/Protobuf/FieldMask.php b/php/src/Google/Protobuf/FieldMask.php index e18586affb..8fb38cbfb2 100644 --- a/php/src/Google/Protobuf/FieldMask.php +++ b/php/src/Google/Protobuf/FieldMask.php @@ -162,6 +162,10 @@ use Google\Protobuf\Internal\GPBUtil; * } * Note that oneof type names ("test_oneof" in this case) cannot be used in * paths. + * ## Field Mask Verification + * The implementation of any API method which has a FieldMask type field in the + * request should verify the included field paths, and return an + * `INVALID_ARGUMENT` error if any path is duplicated or unmappable. * * Generated from protobuf message google.protobuf.FieldMask */ @@ -174,9 +178,19 @@ class FieldMask extends \Google\Protobuf\Internal\Message */ private $paths; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string[]|\Google\Protobuf\Internal\RepeatedField $paths + * The set of field mask paths. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\FieldMask::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Field_Cardinality.php b/php/src/Google/Protobuf/Field_Cardinality.php index 422587ca29..dff8f8931b 100644 --- a/php/src/Google/Protobuf/Field_Cardinality.php +++ b/php/src/Google/Protobuf/Field_Cardinality.php @@ -4,36 +4,13 @@ namespace Google\Protobuf; -/** - * Whether a field is optional, required, or repeated. - * - * Protobuf enum Google\Protobuf\Field\Cardinality - */ -class Field_Cardinality -{ +if (false) { /** - * For fields with unknown cardinality. - * - * Generated from protobuf enum CARDINALITY_UNKNOWN = 0; + * This class is deprecated. Use Google\Protobuf\Field\Cardinality instead. + * @deprecated */ - const CARDINALITY_UNKNOWN = 0; - /** - * For optional fields. - * - * Generated from protobuf enum CARDINALITY_OPTIONAL = 1; - */ - const CARDINALITY_OPTIONAL = 1; - /** - * For required fields. Proto2 syntax only. - * - * Generated from protobuf enum CARDINALITY_REQUIRED = 2; - */ - const CARDINALITY_REQUIRED = 2; - /** - * For repeated fields. - * - * Generated from protobuf enum CARDINALITY_REPEATED = 3; - */ - const CARDINALITY_REPEATED = 3; + class Field_Cardinality {} } +class_exists(Field\Cardinality::class); +@trigger_error('Google\Protobuf\Field_Cardinality is deprecated and will be removed in the next major release. Use Google\Protobuf\Field\Cardinality instead', E_USER_DEPRECATED); diff --git a/php/src/Google/Protobuf/Field_Kind.php b/php/src/Google/Protobuf/Field_Kind.php index d0774970b2..aa20237047 100644 --- a/php/src/Google/Protobuf/Field_Kind.php +++ b/php/src/Google/Protobuf/Field_Kind.php @@ -4,126 +4,13 @@ namespace Google\Protobuf; -/** - * Basic field types. - * - * Protobuf enum Google\Protobuf\Field\Kind - */ -class Field_Kind -{ +if (false) { /** - * Field type unknown. - * - * Generated from protobuf enum TYPE_UNKNOWN = 0; + * This class is deprecated. Use Google\Protobuf\Field\Kind instead. + * @deprecated */ - const TYPE_UNKNOWN = 0; - /** - * Field type double. - * - * Generated from protobuf enum TYPE_DOUBLE = 1; - */ - const TYPE_DOUBLE = 1; - /** - * Field type float. - * - * Generated from protobuf enum TYPE_FLOAT = 2; - */ - const TYPE_FLOAT = 2; - /** - * Field type int64. - * - * Generated from protobuf enum TYPE_INT64 = 3; - */ - const TYPE_INT64 = 3; - /** - * Field type uint64. - * - * Generated from protobuf enum TYPE_UINT64 = 4; - */ - const TYPE_UINT64 = 4; - /** - * Field type int32. - * - * Generated from protobuf enum TYPE_INT32 = 5; - */ - const TYPE_INT32 = 5; - /** - * Field type fixed64. - * - * Generated from protobuf enum TYPE_FIXED64 = 6; - */ - const TYPE_FIXED64 = 6; - /** - * Field type fixed32. - * - * Generated from protobuf enum TYPE_FIXED32 = 7; - */ - const TYPE_FIXED32 = 7; - /** - * Field type bool. - * - * Generated from protobuf enum TYPE_BOOL = 8; - */ - const TYPE_BOOL = 8; - /** - * Field type string. - * - * Generated from protobuf enum TYPE_STRING = 9; - */ - const TYPE_STRING = 9; - /** - * Field type group. Proto2 syntax only, and deprecated. - * - * Generated from protobuf enum TYPE_GROUP = 10; - */ - const TYPE_GROUP = 10; - /** - * Field type message. - * - * Generated from protobuf enum TYPE_MESSAGE = 11; - */ - const TYPE_MESSAGE = 11; - /** - * Field type bytes. - * - * Generated from protobuf enum TYPE_BYTES = 12; - */ - const TYPE_BYTES = 12; - /** - * Field type uint32. - * - * Generated from protobuf enum TYPE_UINT32 = 13; - */ - const TYPE_UINT32 = 13; - /** - * Field type enum. - * - * Generated from protobuf enum TYPE_ENUM = 14; - */ - const TYPE_ENUM = 14; - /** - * Field type sfixed32. - * - * Generated from protobuf enum TYPE_SFIXED32 = 15; - */ - const TYPE_SFIXED32 = 15; - /** - * Field type sfixed64. - * - * Generated from protobuf enum TYPE_SFIXED64 = 16; - */ - const TYPE_SFIXED64 = 16; - /** - * Field type sint32. - * - * Generated from protobuf enum TYPE_SINT32 = 17; - */ - const TYPE_SINT32 = 17; - /** - * Field type sint64. - * - * Generated from protobuf enum TYPE_SINT64 = 18; - */ - const TYPE_SINT64 = 18; + class Field_Kind {} } +class_exists(Field\Kind::class); +@trigger_error('Google\Protobuf\Field_Kind is deprecated and will be removed in the next major release. Use Google\Protobuf\Field\Kind instead', E_USER_DEPRECATED); diff --git a/php/src/Google/Protobuf/FloatValue.php b/php/src/Google/Protobuf/FloatValue.php index 68787ef999..47ba52e6af 100644 --- a/php/src/Google/Protobuf/FloatValue.php +++ b/php/src/Google/Protobuf/FloatValue.php @@ -23,9 +23,19 @@ class FloatValue extends \Google\Protobuf\Internal\Message */ private $value = 0.0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type float $value + * The float value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/GPBEmpty.php b/php/src/Google/Protobuf/GPBEmpty.php index 24a93f9681..2de9c3bc06 100644 --- a/php/src/Google/Protobuf/GPBEmpty.php +++ b/php/src/Google/Protobuf/GPBEmpty.php @@ -22,9 +22,17 @@ use Google\Protobuf\Internal\GPBUtil; class GPBEmpty extends \Google\Protobuf\Internal\Message { - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\GPBEmpty::initOnce(); - parent::__construct(); + parent::__construct($data); } } diff --git a/php/src/Google/Protobuf/Int32Value.php b/php/src/Google/Protobuf/Int32Value.php index d48aff1b91..d7fd528d21 100644 --- a/php/src/Google/Protobuf/Int32Value.php +++ b/php/src/Google/Protobuf/Int32Value.php @@ -23,9 +23,19 @@ class Int32Value extends \Google\Protobuf\Internal\Message */ private $value = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $value + * The int32 value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Int64Value.php b/php/src/Google/Protobuf/Int64Value.php index a6fb9c5dad..ca66305583 100644 --- a/php/src/Google/Protobuf/Int64Value.php +++ b/php/src/Google/Protobuf/Int64Value.php @@ -23,9 +23,19 @@ class Int64Value extends \Google\Protobuf\Internal\Message */ private $value = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int|string $value + * The int64 value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto.php b/php/src/Google/Protobuf/Internal/DescriptorProto.php index 4676269e46..3b215d52ae 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto.php @@ -82,10 +82,10 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message * @type \Google\Protobuf\Internal\FieldDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $extension * @type \Google\Protobuf\Internal\DescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $nested_type * @type \Google\Protobuf\Internal\EnumDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $enum_type - * @type \Google\Protobuf\Internal\DescriptorProto_ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $extension_range + * @type \Google\Protobuf\Internal\DescriptorProto\ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $extension_range * @type \Google\Protobuf\Internal\OneofDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $oneof_decl * @type \Google\Protobuf\Internal\MessageOptions $options - * @type \Google\Protobuf\Internal\DescriptorProto_ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range + * @type \Google\Protobuf\Internal\DescriptorProto\ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range * @type string[]|\Google\Protobuf\Internal\RepeatedField $reserved_name * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. @@ -247,12 +247,12 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - * @param \Google\Protobuf\Internal\DescriptorProto_ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $var + * @param \Google\Protobuf\Internal\DescriptorProto\ExtensionRange[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setExtensionRange($var) { - $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class); + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class); $this->extension_range = $arr; $this->has_extension_range = true; @@ -331,12 +331,12 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; - * @param \Google\Protobuf\Internal\DescriptorProto_ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var + * @param \Google\Protobuf\Internal\DescriptorProto\ReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setReservedRange($var) { - $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class); + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class); $this->reserved_range = $arr; $this->has_reserved_range = true; diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php similarity index 91% rename from php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php rename to php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php index d926ee6e80..c06a0a6ea9 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php @@ -2,7 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\DescriptorProto; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBWire; @@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil; /** * Generated from protobuf message google.protobuf.DescriptorProto.ExtensionRange */ -class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message +class ExtensionRange extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional int32 start = 1; @@ -133,3 +133,6 @@ class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(ExtensionRange::class, \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class); + diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php similarity index 89% rename from php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php rename to php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php index 302eaaa948..73c964faa0 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php @@ -2,7 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\DescriptorProto; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBWire; @@ -17,7 +17,7 @@ use Google\Protobuf\Internal\GPBUtil; * * Generated from protobuf message google.protobuf.DescriptorProto.ReservedRange */ -class DescriptorProto_ReservedRange extends \Google\Protobuf\Internal\Message +class ReservedRange extends \Google\Protobuf\Internal\Message { /** * Inclusive. @@ -117,3 +117,6 @@ class DescriptorProto_ReservedRange extends \Google\Protobuf\Internal\Message } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(ReservedRange::class, \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class); + diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php index 406bb5b50d..da30fa9906 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php @@ -59,7 +59,7 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message * @type string $name * @type \Google\Protobuf\Internal\EnumValueDescriptorProto[]|\Google\Protobuf\Internal\RepeatedField $value * @type \Google\Protobuf\Internal\EnumOptions $options - * @type \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range + * @type \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $reserved_range * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not * overlap. @@ -176,12 +176,12 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message * overlap. * * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; - * @param \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var + * @param \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setReservedRange($var) { - $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange::class); + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class); $this->reserved_range = $arr; $this->has_reserved_range = true; diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php similarity index 89% rename from php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php rename to php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php index 3d7b008eb8..e1079585ec 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php @@ -2,7 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\EnumDescriptorProto; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBWire; @@ -19,7 +19,7 @@ use Google\Protobuf\Internal\GPBUtil; * * Generated from protobuf message google.protobuf.EnumDescriptorProto.EnumReservedRange */ -class EnumDescriptorProto_EnumReservedRange extends \Google\Protobuf\Internal\Message +class EnumReservedRange extends \Google\Protobuf\Internal\Message { /** * Inclusive. @@ -119,3 +119,6 @@ class EnumDescriptorProto_EnumReservedRange extends \Google\Protobuf\Internal\Me } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(EnumReservedRange::class, \Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange::class); + diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php similarity index 61% rename from php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php rename to php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php index f2a32fdf21..b105088e6a 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php @@ -2,12 +2,12 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\FieldDescriptorProto; /** - * Protobuf enum Google\Protobuf\Internal + * Protobuf type google.protobuf.FieldDescriptorProto.Label */ -class FieldDescriptorProto_Label +class Label { /** * 0 is reserved for errors @@ -25,3 +25,6 @@ class FieldDescriptorProto_Label const LABEL_REPEATED = 3; } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Label::class, \Google\Protobuf\Internal\FieldDescriptorProto_Label::class); + diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php similarity index 90% rename from php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php rename to php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php index 1b022debe8..ea228a77fe 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php @@ -2,12 +2,12 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\FieldDescriptorProto; /** - * Protobuf enum Google\Protobuf\Internal + * Protobuf type google.protobuf.FieldDescriptorProto.Type */ -class FieldDescriptorProto_Type +class Type { /** * 0 is reserved for errors. @@ -105,3 +105,6 @@ class FieldDescriptorProto_Type const TYPE_SINT64 = 18; } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Type::class, \Google\Protobuf\Internal\FieldDescriptorProto_Type::class); + diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_CType.php b/php/src/Google/Protobuf/Internal/FieldOptions/CType.php similarity index 61% rename from php/src/Google/Protobuf/Internal/FieldOptions_CType.php rename to php/src/Google/Protobuf/Internal/FieldOptions/CType.php index 0f33072d11..016197acb5 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions_CType.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions/CType.php @@ -2,12 +2,12 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\FieldOptions; /** - * Protobuf enum Google\Protobuf\Internal + * Protobuf type google.protobuf.FieldOptions.CType */ -class FieldOptions_CType +class CType { /** * Default mode. @@ -25,3 +25,6 @@ class FieldOptions_CType const STRING_PIECE = 2; } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(CType::class, \Google\Protobuf\Internal\FieldOptions_CType::class); + diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php b/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php similarity index 65% rename from php/src/Google/Protobuf/Internal/FieldOptions_JSType.php rename to php/src/Google/Protobuf/Internal/FieldOptions/JSType.php index 73bdf3f20e..f7b78a1b31 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php @@ -2,12 +2,12 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\FieldOptions; /** - * Protobuf enum Google\Protobuf\Internal + * Protobuf type google.protobuf.FieldOptions.JSType */ -class FieldOptions_JSType +class JSType { /** * Use the default type. @@ -29,3 +29,6 @@ class FieldOptions_JSType const JS_NUMBER = 2; } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(JSType::class, \Google\Protobuf\Internal\FieldOptions_JSType::class); + diff --git a/php/src/Google/Protobuf/Internal/FileOptions.php b/php/src/Google/Protobuf/Internal/FileOptions.php index 2315ed5e2e..c6b36bbc89 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions.php +++ b/php/src/Google/Protobuf/Internal/FileOptions.php @@ -278,6 +278,14 @@ class FileOptions extends \Google\Protobuf\Internal\Message * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for * determining the namespace. + * @type string $php_metadata_namespace + * Use this option to change the namespace of php generated metadata classes. + * Default is empty. When this option is empty, the proto file name will be used + * for determining the namespace. + * @type string $ruby_package + * Use this option to change the package of ruby generated classes. Default + * is empty. When this option is not set, the package name will be used for + * determining the ruby package. * @type \Google\Protobuf\Internal\UninterpretedOption[]|\Google\Protobuf\Internal\RepeatedField $uninterpreted_option * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. diff --git a/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php b/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php similarity index 67% rename from php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php rename to php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php index 4dd56ef893..3dd60bf6e1 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php +++ b/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php @@ -2,14 +2,14 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\FileOptions; /** * Generated classes can be optimized for speed or code size. * - * Protobuf enum Google\Protobuf\Internal + * Protobuf type google.protobuf.FileOptions.OptimizeMode */ -class FileOptions_OptimizeMode +class OptimizeMode { /** * Generate complete code for parsing, serialization, @@ -31,3 +31,6 @@ class FileOptions_OptimizeMode const LITE_RUNTIME = 3; } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(OptimizeMode::class, \Google\Protobuf\Internal\FileOptions_OptimizeMode::class); + diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php index 05d5c39382..023b07f4d3 100644 --- a/php/src/Google/Protobuf/Internal/GPBUtil.php +++ b/php/src/Google/Protobuf/Internal/GPBUtil.php @@ -191,7 +191,7 @@ class GPBUtil $var = boolval($var); } - public static function checkMessage(&$var, $klass) + public static function checkMessage(&$var, $klass, $newClass = null) { if (!$var instanceof $klass && !is_null($var)) { throw new \Exception("Expect $klass."); @@ -303,8 +303,11 @@ class GPBUtil $name, $file_proto) { - $classname = implode('_', explode('.', $name)); - return static::getClassNamePrefix($classname, $file_proto) . $classname; + $parts = explode('.', $name); + foreach ($parts as $i => $part) { + $parts[$i] = static::getClassNamePrefix($parts[$i], $file_proto) . $parts[$i]; + } + return implode('\\', $parts); } public static function getFullClassName( @@ -347,9 +350,14 @@ class GPBUtil if ($package === "") { $classname = $class_name_without_package; } else { + $parts = array_map('ucwords', explode('.', $package)); + foreach ($parts as $i => $part) { + $parts[$i] = self::getClassNamePrefix($part, $file_proto).$part; + } $classname = - implode('\\', array_map('ucwords', explode('.', $package))). - "\\".$class_name_without_package; + implode('\\', $parts) . + "\\".self::getClassNamePrefix($class_name_without_package,$file_proto). + $class_name_without_package; } } diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php index c2b41a2982..f5a65bea46 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php @@ -34,7 +34,7 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message * @param array $data { * Optional. Data for populating the Message object. * - * @type \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation[]|\Google\Protobuf\Internal\RepeatedField $annotation + * @type \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation[]|\Google\Protobuf\Internal\RepeatedField $annotation * An Annotation connects some span of text in generated code to an element * of its generating .proto file. * } @@ -61,12 +61,12 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message * of its generating .proto file. * * Generated from protobuf field repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; - * @param \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation[]|\Google\Protobuf\Internal\RepeatedField $var + * @param \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAnnotation($var) { - $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class); + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class); $this->annotation = $arr; $this->has_annotation = true; diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php similarity index 95% rename from php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php rename to php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php index 75182007d3..09f958d251 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php @@ -2,7 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\GeneratedCodeInfo; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBWire; @@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil; /** * Generated from protobuf message google.protobuf.GeneratedCodeInfo.Annotation */ -class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message +class Annotation extends \Google\Protobuf\Internal\Message { /** * Identifies the element in the original source .proto file. This field @@ -211,3 +211,6 @@ class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Annotation::class, \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class); + diff --git a/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php b/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php similarity index 70% rename from php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php rename to php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php index 9e06d8eea5..dcc30e271c 100644 --- a/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php +++ b/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php @@ -2,16 +2,16 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\MethodOptions; /** * Is this method side-effect-free (or safe in HTTP parlance), or idempotent, * or neither? HTTP based RPC implementation may choose GET verb for safe * methods, and PUT verb for idempotent methods instead of the default POST. * - * Protobuf enum Google\Protobuf\Internal + * Protobuf type google.protobuf.MethodOptions.IdempotencyLevel */ -class MethodOptions_IdempotencyLevel +class IdempotencyLevel { /** * Generated from protobuf enum IDEMPOTENCY_UNKNOWN = 0; @@ -31,3 +31,6 @@ class MethodOptions_IdempotencyLevel const IDEMPOTENT = 2; } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(IdempotencyLevel::class, \Google\Protobuf\Internal\MethodOptions_IdempotencyLevel::class); + diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php index 2305a79201..6e413f77a2 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php @@ -72,7 +72,7 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message * @param array $data { * Optional. Data for populating the Message object. * - * @type \Google\Protobuf\Internal\SourceCodeInfo_Location[]|\Google\Protobuf\Internal\RepeatedField $location + * @type \Google\Protobuf\Internal\SourceCodeInfo\Location[]|\Google\Protobuf\Internal\RepeatedField $location * A Location identifies a piece of source code in a .proto file which * corresponds to a particular definition. This information is intended * to be useful to IDEs, code indexers, documentation generators, and similar @@ -216,12 +216,12 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message * be recorded in the future. * * Generated from protobuf field repeated .google.protobuf.SourceCodeInfo.Location location = 1; - * @param \Google\Protobuf\Internal\SourceCodeInfo_Location[]|\Google\Protobuf\Internal\RepeatedField $var + * @param \Google\Protobuf\Internal\SourceCodeInfo\Location[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLocation($var) { - $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo_Location::class); + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo\Location::class); $this->location = $arr; $this->has_location = true; diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php similarity index 98% rename from php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php rename to php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php index f930aac101..bad247a11f 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php @@ -2,7 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\SourceCodeInfo; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBWire; @@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil; /** * Generated from protobuf message google.protobuf.SourceCodeInfo.Location */ -class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message +class Location extends \Google\Protobuf\Internal\Message { /** * Identifies which part of the FileDescriptorProto was defined at this @@ -458,3 +458,6 @@ class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(Location::class, \Google\Protobuf\Internal\SourceCodeInfo_Location::class); + diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption.php b/php/src/Google/Protobuf/Internal/UninterpretedOption.php index 36a18688cf..3b517ec552 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption.php @@ -67,7 +67,7 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message * @param array $data { * Optional. Data for populating the Message object. * - * @type \Google\Protobuf\Internal\UninterpretedOption_NamePart[]|\Google\Protobuf\Internal\RepeatedField $name + * @type \Google\Protobuf\Internal\UninterpretedOption\NamePart[]|\Google\Protobuf\Internal\RepeatedField $name * @type string $identifier_value * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. @@ -94,12 +94,12 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - * @param \Google\Protobuf\Internal\UninterpretedOption_NamePart[]|\Google\Protobuf\Internal\RepeatedField $var + * @param \Google\Protobuf\Internal\UninterpretedOption\NamePart[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setName($var) { - $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class); + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption\NamePart::class); $this->name = $arr; $this->has_name = true; diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php similarity index 90% rename from php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php rename to php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php index d4369fda4c..92ee4b44b9 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php @@ -2,7 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto -namespace Google\Protobuf\Internal; +namespace Google\Protobuf\Internal\UninterpretedOption; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBWire; @@ -19,7 +19,7 @@ use Google\Protobuf\Internal\GPBUtil; * * Generated from protobuf message google.protobuf.UninterpretedOption.NamePart */ -class UninterpretedOption_NamePart extends \Google\Protobuf\Internal\Message +class NamePart extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field required string name_part = 1; @@ -105,3 +105,6 @@ class UninterpretedOption_NamePart extends \Google\Protobuf\Internal\Message } +// Adding a class alias for backwards compatibility with the previous class name. +class_alias(NamePart::class, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class); + diff --git a/php/src/Google/Protobuf/ListValue.php b/php/src/Google/Protobuf/ListValue.php index 12552ef4b8..70f542326f 100644 --- a/php/src/Google/Protobuf/ListValue.php +++ b/php/src/Google/Protobuf/ListValue.php @@ -23,9 +23,19 @@ class ListValue extends \Google\Protobuf\Internal\Message */ private $values; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \Google\Protobuf\Value[]|\Google\Protobuf\Internal\RepeatedField $values + * Repeated field of dynamically typed values. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Struct::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Method.php b/php/src/Google/Protobuf/Method.php index f55cb76424..8e80350688 100644 --- a/php/src/Google/Protobuf/Method.php +++ b/php/src/Google/Protobuf/Method.php @@ -58,9 +58,31 @@ class Method extends \Google\Protobuf\Internal\Message */ private $syntax = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * The simple name of this method. + * @type string $request_type_url + * A URL of the input message type. + * @type bool $request_streaming + * If true, the request is streamed. + * @type string $response_type_url + * The URL of the output message type. + * @type bool $response_streaming + * If true, the response is streamed. + * @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options + * Any metadata attached to the method. + * @type int $syntax + * The source syntax of this method. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Api::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Mixin.php b/php/src/Google/Protobuf/Mixin.php index eb5117e080..a2ea59c757 100644 --- a/php/src/Google/Protobuf/Mixin.php +++ b/php/src/Google/Protobuf/Mixin.php @@ -90,9 +90,22 @@ class Mixin extends \Google\Protobuf\Internal\Message */ private $root = ''; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * The fully qualified name of the interface which is included. + * @type string $root + * If non-empty specifies a path under which inherited HTTP paths + * are rooted. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Api::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/NullValue.php b/php/src/Google/Protobuf/NullValue.php index d4022cccdd..482b80dde5 100644 --- a/php/src/Google/Protobuf/NullValue.php +++ b/php/src/Google/Protobuf/NullValue.php @@ -9,7 +9,7 @@ namespace Google\Protobuf; * `Value` type union. * The JSON representation for `NullValue` is JSON `null`. * - * Protobuf enum Google\Protobuf\NullValue + * Protobuf type google.protobuf.NullValue */ class NullValue { diff --git a/php/src/Google/Protobuf/Option.php b/php/src/Google/Protobuf/Option.php index f80386813a..22ecfc5f5c 100644 --- a/php/src/Google/Protobuf/Option.php +++ b/php/src/Google/Protobuf/Option.php @@ -35,9 +35,27 @@ class Option extends \Google\Protobuf\Internal\Message */ private $value = null; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * The option's name. For protobuf built-in options (options defined in + * descriptor.proto), this is the short name. For example, `"map_entry"`. + * For custom options, it should be the fully-qualified name. For example, + * `"google.api.http"`. + * @type \Google\Protobuf\Any $value + * The option's value packed in an Any message. If the value is a primitive, + * the corresponding wrapper type defined in google/protobuf/wrappers.proto + * should be used. If the value is an enum, it should be stored as an int32 + * value using the google.protobuf.Int32Value type. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/SourceContext.php b/php/src/Google/Protobuf/SourceContext.php index 07d90c6812..cbc50c6842 100644 --- a/php/src/Google/Protobuf/SourceContext.php +++ b/php/src/Google/Protobuf/SourceContext.php @@ -24,9 +24,20 @@ class SourceContext extends \Google\Protobuf\Internal\Message */ private $file_name = ''; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $file_name + * The path-qualified name of the .proto file that contained the associated + * protobuf element. For example: `"google/protobuf/source_context.proto"`. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\SourceContext::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/StringValue.php b/php/src/Google/Protobuf/StringValue.php index f6bcc48a75..8fb354f388 100644 --- a/php/src/Google/Protobuf/StringValue.php +++ b/php/src/Google/Protobuf/StringValue.php @@ -23,9 +23,19 @@ class StringValue extends \Google\Protobuf\Internal\Message */ private $value = ''; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $value + * The string value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Struct.php b/php/src/Google/Protobuf/Struct.php index 721e991c31..0456541cbd 100644 --- a/php/src/Google/Protobuf/Struct.php +++ b/php/src/Google/Protobuf/Struct.php @@ -28,9 +28,19 @@ class Struct extends \Google\Protobuf\Internal\Message */ private $fields; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type array|\Google\Protobuf\Internal\MapField $fields + * Unordered map of dynamically typed values. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Struct::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Syntax.php b/php/src/Google/Protobuf/Syntax.php index bb7b789650..3a52dc9e1c 100644 --- a/php/src/Google/Protobuf/Syntax.php +++ b/php/src/Google/Protobuf/Syntax.php @@ -7,7 +7,7 @@ namespace Google\Protobuf; /** * The syntax in which a protocol buffer element is defined. * - * Protobuf enum Google\Protobuf\Syntax + * Protobuf type google.protobuf.Syntax */ class Syntax { diff --git a/php/src/Google/Protobuf/Timestamp.php b/php/src/Google/Protobuf/Timestamp.php index f2286ab4bb..e21f3231cb 100644 --- a/php/src/Google/Protobuf/Timestamp.php +++ b/php/src/Google/Protobuf/Timestamp.php @@ -89,9 +89,26 @@ class Timestamp extends \Google\Protobuf\Internal\Message */ private $nanos = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int|string $seconds + * Represents seconds of UTC time since Unix epoch + * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + * 9999-12-31T23:59:59Z inclusive. + * @type int $nanos + * Non-negative fractions of a second at nanosecond resolution. Negative + * second values with fractions must still have non-negative nanos values + * that count forward in time. Must be from 0 to 999,999,999 + * inclusive. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Timestamp::initOnce(); - parent::__construct(); + parent::__construct($data); } /** @@ -156,7 +173,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message return $this; } - /** + /* * Converts PHP DateTime to Timestamp. * * @param \DateTime $datetime diff --git a/php/src/Google/Protobuf/Type.php b/php/src/Google/Protobuf/Type.php index 7dbe2cab27..1b47811050 100644 --- a/php/src/Google/Protobuf/Type.php +++ b/php/src/Google/Protobuf/Type.php @@ -52,9 +52,29 @@ class Type extends \Google\Protobuf\Internal\Message */ private $syntax = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $name + * The fully qualified message name. + * @type \Google\Protobuf\Field[]|\Google\Protobuf\Internal\RepeatedField $fields + * The list of fields. + * @type string[]|\Google\Protobuf\Internal\RepeatedField $oneofs + * The list of types appearing in `oneof` definitions in this type. + * @type \Google\Protobuf\Option[]|\Google\Protobuf\Internal\RepeatedField $options + * The protocol buffer options. + * @type \Google\Protobuf\SourceContext $source_context + * The source context. + * @type int $syntax + * The source syntax. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/UInt32Value.php b/php/src/Google/Protobuf/UInt32Value.php index 61a3ddf150..f5a522d2e8 100644 --- a/php/src/Google/Protobuf/UInt32Value.php +++ b/php/src/Google/Protobuf/UInt32Value.php @@ -23,9 +23,19 @@ class UInt32Value extends \Google\Protobuf\Internal\Message */ private $value = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $value + * The uint32 value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/UInt64Value.php b/php/src/Google/Protobuf/UInt64Value.php index 69f7eb8e40..89e69cd892 100644 --- a/php/src/Google/Protobuf/UInt64Value.php +++ b/php/src/Google/Protobuf/UInt64Value.php @@ -23,9 +23,19 @@ class UInt64Value extends \Google\Protobuf\Internal\Message */ private $value = 0; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int|string $value + * The uint64 value. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/src/Google/Protobuf/Value.php b/php/src/Google/Protobuf/Value.php index 052a377918..5c1e864c3d 100644 --- a/php/src/Google/Protobuf/Value.php +++ b/php/src/Google/Protobuf/Value.php @@ -21,9 +21,29 @@ class Value extends \Google\Protobuf\Internal\Message { protected $kind; - public function __construct() { + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $null_value + * Represents a null value. + * @type float $number_value + * Represents a double value. + * @type string $string_value + * Represents a string value. + * @type bool $bool_value + * Represents a boolean value. + * @type \Google\Protobuf\Struct $struct_value + * Represents a structured value. + * @type \Google\Protobuf\ListValue $list_value + * Represents a repeated `Value`. + * } + */ + public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Struct::initOnce(); - parent::__construct(); + parent::__construct($data); } /** diff --git a/php/tests/array_test.php b/php/tests/array_test.php index 1a26d72a88..36a649ed19 100644 --- a/php/tests/array_test.php +++ b/php/tests/array_test.php @@ -5,7 +5,7 @@ require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\GPBType; use Foo\TestMessage; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; class RepeatedFieldTest extends PHPUnit_Framework_TestCase { @@ -456,10 +456,10 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase public function testMessage() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); // Test append. - $sub_m = new TestMessage_Sub(); + $sub_m = new Sub(); $sub_m->setA(1); $arr[] = $sub_m; $this->assertSame(1, $arr[0]->getA()); @@ -467,15 +467,15 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase $this->assertEquals(1, count($arr)); // Test set. - $sub_m = new TestMessage_Sub(); + $sub_m = new Sub(); $sub_m->setA(2); $arr[0] = $sub_m; $this->assertSame(2, $arr[0]->getA()); // Test foreach. - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); for ($i = 0; $i < 3; $i++) { - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); $arr[$i]->setA($i); } $i = 0; diff --git a/php/tests/descriptors_test.php b/php/tests/descriptors_test.php index 17e8a4f2fd..93683b82fd 100644 --- a/php/tests/descriptors_test.php +++ b/php/tests/descriptors_test.php @@ -10,7 +10,7 @@ use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\MapField; use Descriptors\TestDescriptorsEnum; use Descriptors\TestDescriptorsMessage; -use Descriptors\TestDescriptorsMessage_Sub; +use Descriptors\TestDescriptorsMessage\Sub; class DescriptorsTest extends TestBase { diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php index 74d5526d51..d36b883e1e 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/encode_decode_test.php @@ -7,7 +7,7 @@ use Google\Protobuf\RepeatedField; use Google\Protobuf\GPBType; use Foo\TestEnum; use Foo\TestMessage; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; use Foo\TestPackedMessage; use Foo\TestRandomFieldOrder; use Foo\TestUnpackedMessage; @@ -82,7 +82,7 @@ class EncodeDecodeTest extends TestBase $n->mergeFromString($data); $this->assertSame('abc', $n->getOneofString()); - $sub_m = new TestMessage_Sub(); + $sub_m = new Sub(); $sub_m->setA(1); $m->setOneofMessage($sub_m); $data = $m->serializeToString(); @@ -105,7 +105,7 @@ class EncodeDecodeTest extends TestBase $this->assertSame("oneof_string", $n->getMyOneof()); $this->assertSame("", $n->getOneofString()); - $sub_m = new TestMessage_Sub(); + $sub_m = new Sub(); $m->setOneofMessage($sub_m); $data = $m->serializeToString(); $n = new TestMessage(); diff --git a/php/tests/gdb_test.sh b/php/tests/gdb_test.sh index a5f6306ed6..36fa31bbb2 100755 --- a/php/tests/gdb_test.sh +++ b/php/tests/gdb_test.sh @@ -11,8 +11,8 @@ php -i | grep "Configuration" # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which # phpunit` --bootstrap autoload.php tmp_test.php # -# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php +gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php generated_class_test.php # -gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php +# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php # # USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index fbee29bc5b..9f20bddc17 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -8,14 +8,20 @@ require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\MapField; use Google\Protobuf\Internal\GPBType; +use Bar\TestLegacyMessage; +use Bar\TestLegacyMessage_NestedEnum; +use Bar\TestLegacyMessage_NestedMessage; use Foo\TestEnum; use Foo\TestIncludeNamespaceMessage; use Foo\TestIncludePrefixMessage; use Foo\TestMessage; +use Foo\TestMessage\Sub; use Foo\TestMessage_Sub; +use Foo\TestMessage\NestedEnum; use Foo\TestReverseFieldOrder; use Foo\testLowerCaseMessage; use Foo\testLowerCaseEnum; +use PBEmpty\PBEcho\TestEmptyPackage; use Php\Test\TestNamespace; class GeneratedClassTest extends TestBase @@ -229,11 +235,28 @@ class GeneratedClassTest extends TestBase } public function testNestedEnum() + { + $m = new TestMessage(); + $m->setOptionalNestedEnum(NestedEnum::ZERO); + } + + public function testLegacyNestedEnum() { $m = new TestMessage(); $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO); } + public function testLegacyTypehintWithNestedEnums() + { + $this->legacyEnum(new TestLegacyMessage\NestedEnum); + } + + private function legacyEnum(TestLegacyMessage_NestedEnum $enum) + { + // If we made it here without a PHP Fatal error, the typehint worked + $this->assertTrue(true); + } + ######################################################### # Test float field. ######################################################### @@ -370,6 +393,20 @@ class GeneratedClassTest extends TestBase { $m = new TestMessage(); + $sub_m = new Sub(); + $sub_m->setA(1); + $m->setOptionalMessage($sub_m); + $this->assertSame(1, $m->getOptionalMessage()->getA()); + + $null = null; + $m->setOptionalMessage($null); + $this->assertNull($m->getOptionalMessage()); + } + + public function testLegacyMessageField() + { + $m = new TestMessage(); + $sub_m = new TestMessage_Sub(); $sub_m->setA(1); $m->setOptionalMessage($sub_m); @@ -380,6 +417,17 @@ class GeneratedClassTest extends TestBase $this->assertNull($m->getOptionalMessage()); } + public function testLegacyTypehintWithNestedMessages() + { + $this->legacyMessage(new TestLegacyMessage\NestedMessage); + } + + private function legacyMessage(TestLegacyMessage_NestedMessage $sub) + { + // If we made it here without a PHP Fatal error, the typehint worked + $this->assertTrue(true); + } + ######################################################### # Test repeated field. ######################################################### @@ -474,7 +522,7 @@ class GeneratedClassTest extends TestBase $this->assertSame(NULL, $m->getOneofMessage()); $this->assertSame("oneof_string", $m->getMyOneof()); - $sub_m = new TestMessage_Sub(); + $sub_m = new Sub(); $sub_m->setA(1); $m->setOneofMessage($sub_m); $this->assertSame(0, $m->getOneofInt32()); @@ -513,7 +561,7 @@ class GeneratedClassTest extends TestBase // Singular $n->setOptionalInt32(100); - $sub1 = new TestMessage_Sub(); + $sub1 = new Sub(); $sub1->setA(101); $b = $sub1->getB(); @@ -531,7 +579,7 @@ class GeneratedClassTest extends TestBase $repeatedString[] = 'abc'; $n->setRepeatedString($repeatedString); - $sub2 = new TestMessage_Sub(); + $sub2 = new Sub(); $sub2->setA(201); $repeatedMessage = $n->getRepeatedMessage(); $repeatedMessage[] = $sub2; @@ -548,9 +596,9 @@ class GeneratedClassTest extends TestBase $n->setMapStringString($mapStringString); $mapInt32Message = $n->getMapInt32Message(); - $mapInt32Message[1] = new TestMessage_Sub(); + $mapInt32Message[1] = new Sub(); $mapInt32Message[1]->setA(302); - $mapInt32Message[2] = new TestMessage_Sub(); + $mapInt32Message[2] = new Sub(); $mapInt32Message[2]->setA(303); $n->setMapInt32Message($mapInt32Message); @@ -607,7 +655,7 @@ class GeneratedClassTest extends TestBase $m->mergeFrom($n); $this->assertSame(1, $m->getOneofInt32()); - $sub = new TestMessage_Sub(); + $sub = new Sub(); $n->setOneofMessage($sub); $n->getOneofMessage()->setA(400); $m->mergeFrom($n); @@ -630,14 +678,15 @@ class GeneratedClassTest extends TestBase public function testMessageWithoutNamespace() { $m = new TestMessage(); - $sub = new NoNameSpaceMessage(); - $m->setOptionalNoNamespaceMessage($sub); + $n = new NoNameSpaceMessage(); + $m->setOptionalNoNamespaceMessage($n); $repeatedNoNamespaceMessage = $m->getRepeatedNoNamespaceMessage(); $repeatedNoNamespaceMessage[] = new NoNameSpaceMessage(); $m->setRepeatedNoNamespaceMessage($repeatedNoNamespaceMessage); - $n = new NoNamespaceMessage(); - $n->setB(NoNamespaceMessage_NestedEnum::ZERO); + // test nested messages + $sub = new NoNamespaceMessage\NestedMessage(); + $n->setNestedMessage($sub); } public function testEnumWithoutNamespace() @@ -650,35 +699,91 @@ class GeneratedClassTest extends TestBase } ######################################################### - # Test message with given prefix. + # Test message with given namespace. ######################################################### - public function testPrefixMessage() + public function testNestedMessagesAndEnums() + { + $m = new TestMessage(); + $n = new TestMessage\Sub(); + $m->setOptionalMessage($n); + $m->setOptionalNestedEnum(TestMessage\NestedEnum::ZERO); + $this->assertSame($n, $m->getOptionalMessage()); + $this->assertSame(TestMessage\NestedEnum::ZERO, $m->getOptionalNestedEnum()); + } + + public function testMessagesAndEnumsWithPrefix() { + // Test message prefix $m = new TestIncludePrefixMessage(); $n = new PrefixTestPrefix(); $n->setA(1); $m->setPrefixMessage($n); $this->assertSame(1, $m->getPrefixMessage()->getA()); + + // Test nested message prefix + $o = new PrefixTestPrefix(); + $p = new PrefixTestPrefix\PrefixNestedMessage(); + $o->setNestedMessage($p); + $o->setNestedEnum(PrefixTestPrefix\PrefixNestedEnum::ZERO); + $this->assertSame($p, $o->getNestedMessage()); + $this->assertSame(PrefixTestPrefix\PrefixNestedEnum::ZERO, $o->getNestedEnum()); } - ######################################################### - # Test message with given namespace. - ######################################################### + public function testMessagesAndEnumsWithPhpNamespace() + { + $m = new TestNamespace(); + $n = new TestNamespace\NestedMessage(); + $m->setNestedMessage($n); + $m->setNestedEnum(TestNamespace\NestedEnum::ZERO); + $this->assertSame($n, $m->getNestedMessage()); + $this->assertSame(TestNamespace\NestedEnum::ZERO, $m->getNestedEnum()); + } - public function testNamespaceMessage() + public function testMesssagesAndEnumsWithEmptyPhpNamespace() { - $m = new TestIncludeNamespaceMessage(); + $m = new TestEmptyNamespace(); + $n = new TestEmptyNamespace\NestedMessage(); + $m->setNestedMessage($n); + $m->setNestedEnum(TestEmptyNamespace\NestedEnum::ZERO); + $this->assertSame($n, $m->getNestedMessage()); + $this->assertSame(TestEmptyNamespace\NestedEnum::ZERO, $m->getNestedEnum()); + } - $n = new TestNamespace(); - $n->setA(1); - $m->setNamespaceMessage($n); - $this->assertSame(1, $m->getNamespaceMessage()->getA()); + public function testMessagesAndEnumsWithNoNamespace() + { + $m = new NoNamespaceMessage(); + $n = new NoNamespaceMessage\NestedMessage(); + $m->setNestedMessage($n); + $m->setNestedEnum(NoNamespaceMessage\NestedEnum::ZERO); + $this->assertSame($n, $m->getNestedMessage()); + $this->assertSame(NoNamespaceMessage\NestedEnum::ZERO, $m->getNestedEnum()); + } - $n = new TestEmptyNamespace(); - $n->setA(1); - $m->setEmptyNamespaceMessage($n); - $this->assertSame(1, $m->getEmptyNamespaceMessage()->getA()); + public function testReservedWordsInPackageName() + { + $m = new TestEmptyPackage(); + $n = new TestEmptyPackage\NestedMessage(); + $m->setNestedMessage($n); + $m->setNestedEnum(TestEmptyPackage\NestedEnum::ZERO); + $this->assertSame($n, $m->getNestedMessage()); + $this->assertSame(TestEmptyPackage\NestedEnum::ZERO, $m->getNestedEnum()); + } + + public function testReservedWordsInNamespace() + { + $m = new TestNamespace(); + $n = new TestNamespace\PBEmpty(); + $o = new TestNamespace\PBEmpty\NestedMessage(); + $n->setNestedMessage($o); + $n->setNestedEnum(TestNamespace\PBEmpty\NestedEnum::ZERO); + $m->setReservedName($n); + $this->assertSame($n, $m->getReservedName()); + $this->assertSame($o, $n->getNestedMessage()); + $this->assertSame( + TestNamespace\PBEmpty\NestedEnum::ZERO, + $n->getNestedEnum() + ); } ######################################################### @@ -687,7 +792,7 @@ class GeneratedClassTest extends TestBase public function testPrefixForReservedWords() { - $m = new \Foo\TestMessage_Empty(); + $m = new \Foo\TestMessage\PBEmpty(); $m = new \Foo\PBEmpty(); $m = new \PrefixEmpty(); $m = new \Foo\PBARRAY(); @@ -1195,7 +1300,7 @@ class GeneratedClassTest extends TestBase 'optional_string' => 'a', 'optional_bytes' => 'b', 'optional_enum' => TestEnum::ONE, - 'optional_message' => new TestMessage_Sub([ + 'optional_message' => new Sub([ 'a' => 33 ]), 'repeated_int32' => [-42, -52], @@ -1214,8 +1319,8 @@ class GeneratedClassTest extends TestBase 'repeated_string' => ['a', 'c'], 'repeated_bytes' => ['b', 'd'], 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], - 'repeated_message' => [new TestMessage_Sub(['a' => 34]), - new TestMessage_Sub(['a' => 35])], + 'repeated_message' => [new Sub(['a' => 34]), + new Sub(['a' => 35])], 'map_int32_int32' => [-62 => -62], 'map_int64_int64' => [-63 => -63], 'map_uint32_uint32' => [62 => 62], @@ -1232,7 +1337,7 @@ class GeneratedClassTest extends TestBase 'map_string_string' => ['e' => 'e'], 'map_int32_bytes' => [1 => 'f'], 'map_int32_enum' => [1 => TestEnum::ONE], - 'map_int32_message' => [1 => new TestMessage_Sub(['a' => 36])], + 'map_int32_message' => [1 => new Sub(['a' => 36])], ]); TestUtil::assertTestMessage($m); diff --git a/php/tests/generated_phpdoc_test.php b/php/tests/generated_phpdoc_test.php index 505dafea73..526927fc28 100644 --- a/php/tests/generated_phpdoc_test.php +++ b/php/tests/generated_phpdoc_test.php @@ -201,7 +201,7 @@ class GeneratedPhpdocTest extends TestBase [ 'setRepeatedMessage', ], - '@param \Foo\TestMessage_Sub[]|\Google\Protobuf\Internal\RepeatedField $var' + '@param \Foo\TestMessage\Sub[]|\Google\Protobuf\Internal\RepeatedField $var' ], [ [ @@ -294,14 +294,14 @@ class GeneratedPhpdocTest extends TestBase 'getOptionalMessage', 'getOneofMessage' ], - '@return \Foo\TestMessage_Sub' + '@return \Foo\TestMessage\Sub' ], [ [ 'setOptionalMessage', 'setOneofMessage' ], - '@param \Foo\TestMessage_Sub $var' + '@param \Foo\TestMessage\Sub $var' ], [ [ diff --git a/php/tests/map_field_test.php b/php/tests/map_field_test.php index cffa2526d0..447bdd9b36 100644 --- a/php/tests/map_field_test.php +++ b/php/tests/map_field_test.php @@ -5,7 +5,7 @@ require_once('test_util.php'); use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\MapField; use Foo\TestMessage; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; class MapFieldTest extends PHPUnit_Framework_TestCase { @@ -408,10 +408,10 @@ class MapFieldTest extends PHPUnit_Framework_TestCase { public function testMessage() { $arr = new MapField(GPBType::INT32, - GPBType::MESSAGE, TestMessage_Sub::class); + GPBType::MESSAGE, Sub::class); // Test append. - $sub_m = new TestMessage_Sub(); + $sub_m = new Sub(); $sub_m->setA(1); $arr[0] = $sub_m; $this->assertSame(1, $arr[0]->getA()); @@ -420,9 +420,9 @@ class MapFieldTest extends PHPUnit_Framework_TestCase { // Test foreach. $arr = new MapField(GPBType::INT32, - GPBType::MESSAGE, TestMessage_Sub::class); + GPBType::MESSAGE, Sub::class); for ($i = 0; $i < 3; $i++) { - $arr[$i] = new TestMessage_Sub();; + $arr[$i] = new Sub();; $arr[$i]->setA($i); } $i = 0; diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index ad55d57870..5456919bcf 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -15,9 +15,9 @@ require_once('generated/Foo/TestEnum.php'); require_once('generated/Foo/TestIncludeNamespaceMessage.php'); require_once('generated/Foo/TestIncludePrefixMessage.php'); require_once('generated/Foo/TestMessage.php'); -require_once('generated/Foo/TestMessage_Empty.php'); -require_once('generated/Foo/TestMessage_NestedEnum.php'); -require_once('generated/Foo/TestMessage_Sub.php'); +require_once('generated/Foo/TestMessage/PBEmpty.php'); +require_once('generated/Foo/TestMessage/NestedEnum.php'); +require_once('generated/Foo/TestMessage/Sub.php'); require_once('generated/Foo/TestPackedMessage.php'); require_once('generated/Foo/TestPhpDoc.php'); require_once('generated/Foo/TestRandomFieldOrder.php'); @@ -37,7 +37,7 @@ require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\GPBType; use Foo\TestMessage; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; $from = new TestMessage(); TestUtil::setTestMessage($from); @@ -97,7 +97,7 @@ $n = new TestMessage(); $n->mergeFromString($data); assert('abc' === $n->getOneofString()); -$sub_m = new TestMessage_Sub(); +$sub_m = new Sub(); $sub_m->setA(1); $m->setOneofMessage($sub_m); assert(0 === $m->getOneofInt32()); diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php index 6481473e45..323a36ff09 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/php_implementation_test.php @@ -5,7 +5,7 @@ require_once('test_util.php'); use Foo\TestEnum; use Foo\TestMessage; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; use Foo\TestPackedMessage; use Google\Protobuf\Internal\CodedInputStream; use Google\Protobuf\Internal\FileDescriptorSet; @@ -527,7 +527,7 @@ class ImplementationTest extends TestBase /** * @expectedException Exception - * @expectedExceptionMessage Expect message. + * @expectedExceptionMessage Expect Foo\TestMessage_Sub. */ public function testArraysForMessagesThrowsException() { diff --git a/php/tests/proto/empty/echo.proto b/php/tests/proto/empty/echo.proto new file mode 100644 index 0000000000..1817018dd2 --- /dev/null +++ b/php/tests/proto/empty/echo.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package empty.echo; + +message TestEmptyPackage { + int32 a = 1; + + // Test nested messages, enums, and reserved names + NestedMessage nested_message = 2; + NestedEnum nested_enum = 3; + message NestedMessage { + int32 a = 1; + } + enum NestedEnum { + ZERO = 0; + }; +} diff --git a/php/tests/proto/test_empty_php_namespace.proto b/php/tests/proto/test_empty_php_namespace.proto index 1d02f76095..c7ed16573e 100644 --- a/php/tests/proto/test_empty_php_namespace.proto +++ b/php/tests/proto/test_empty_php_namespace.proto @@ -6,4 +6,14 @@ option php_metadata_namespace = ""; message TestEmptyNamespace { int32 a = 1; + + // Test nested messages, enums, and reserved names + NestedMessage nested_message = 2; + NestedEnum nested_enum = 3; + message NestedMessage { + int32 a = 1; + } + enum NestedEnum { + ZERO = 0; + }; } diff --git a/php/tests/proto/test_include.proto b/php/tests/proto/test_include.proto index 9844617fa8..a9072fe304 100644 --- a/php/tests/proto/test_include.proto +++ b/php/tests/proto/test_include.proto @@ -5,3 +5,14 @@ package bar; message TestInclude { int32 a = 1; } + +message TestLegacyMessage { + NestedMessage message = 1; + NestedEnum enum = 2; + message NestedMessage { + int32 a = 1; + } + enum NestedEnum { + ZERO = 0; + } +} diff --git a/php/tests/proto/test_no_namespace.proto b/php/tests/proto/test_no_namespace.proto index 03f89270ed..cce42ea2c3 100644 --- a/php/tests/proto/test_no_namespace.proto +++ b/php/tests/proto/test_no_namespace.proto @@ -5,11 +5,15 @@ option php_metadata_namespace = "\\"; message NoNamespaceMessage { int32 a = 1; - enum NestedEnum { - ZERO = 0; + // Test nested messages, enums, and reserved names + NestedMessage nested_message = 2; + NestedEnum nested_enum = 3; + message NestedMessage { + int32 a = 1; } - NestedEnum b = 2; - repeated NestedEnum c = 3; + enum NestedEnum { + ZERO = 0; + }; } enum NoNamespaceEnum { diff --git a/php/tests/proto/test_php_namespace.proto b/php/tests/proto/test_php_namespace.proto index bb57d6177d..61085bf75a 100644 --- a/php/tests/proto/test_php_namespace.proto +++ b/php/tests/proto/test_php_namespace.proto @@ -6,4 +6,26 @@ option php_metadata_namespace = "Metadata\\Php\\Test"; message TestNamespace { int32 a = 1; + + // Test nested messages, enums, and reserved names + NestedMessage nested_message = 2; + NestedEnum nested_enum = 3; + Empty reserved_name = 4; + message NestedMessage { + int32 a = 1; + } + enum NestedEnum { + ZERO = 0; + }; + // Test reserved name + message Empty { + NestedMessage nested_message = 1; + NestedEnum nested_enum = 2; + message NestedMessage { + int32 a = 1; + } + enum NestedEnum { + ZERO = 0; + }; + } } diff --git a/php/tests/proto/test_prefix.proto b/php/tests/proto/test_prefix.proto index 9bfbad7f82..3fa11381b0 100644 --- a/php/tests/proto/test_prefix.proto +++ b/php/tests/proto/test_prefix.proto @@ -4,6 +4,14 @@ option php_class_prefix = "Prefix"; message TestPrefix { int32 a = 1; + NestedMessage nested_message = 2; + NestedEnum nested_enum = 3; + message NestedMessage { + int32 a = 1; + } + enum NestedEnum { + ZERO = 0; + }; } // Test prefix for reserved words. diff --git a/php/tests/test_base.php b/php/tests/test_base.php index dc5e73f579..80f603c77a 100644 --- a/php/tests/test_base.php +++ b/php/tests/test_base.php @@ -2,7 +2,7 @@ use Foo\TestMessage; use Foo\TestEnum; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; class TestBase extends PHPUnit_Framework_TestCase { diff --git a/php/tests/test_util.php b/php/tests/test_util.php index c8afdd3e79..a676d097ed 100644 --- a/php/tests/test_util.php +++ b/php/tests/test_util.php @@ -2,7 +2,7 @@ use Foo\TestEnum; use Foo\TestMessage; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; use Foo\TestPackedMessage; use Foo\TestUnpackedMessage; @@ -67,7 +67,7 @@ class TestUtil $m->setOptionalString('a'); $m->setOptionalBytes('b'); $m->setOptionalEnum(TestEnum::ONE); - $sub = new TestMessage_Sub(); + $sub = new Sub(); $m->setOptionalMessage($sub); $m->getOptionalMessage()->SetA(33); @@ -87,7 +87,7 @@ class TestUtil self::appendHelper($m, 'RepeatedString', 'a'); self::appendHelper($m, 'RepeatedBytes', 'b'); self::appendHelper($m, 'RepeatedEnum', TestEnum::ZERO); - self::appendHelper($m, 'RepeatedMessage', new TestMessage_Sub()); + self::appendHelper($m, 'RepeatedMessage', new Sub()); $m->getRepeatedMessage()[0]->setA(34); self::appendHelper($m, 'RepeatedInt32', -52); @@ -106,7 +106,7 @@ class TestUtil self::appendHelper($m, 'RepeatedString', 'c'); self::appendHelper($m, 'RepeatedBytes', 'd'); self::appendHelper($m, 'RepeatedEnum', TestEnum::ONE); - self::appendHelper($m, 'RepeatedMessage', new TestMessage_Sub()); + self::appendHelper($m, 'RepeatedMessage', new Sub()); $m->getRepeatedMessage()[1]->SetA(35); self::kvUpdateHelper($m, 'MapInt32Int32', -62, -62); @@ -125,13 +125,13 @@ class TestUtil self::kvUpdateHelper($m, 'MapStringString', 'e', 'e'); self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'f'); self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::ONE); - self::kvUpdateHelper($m, 'MapInt32Message', 1, new TestMessage_Sub()); + self::kvUpdateHelper($m, 'MapInt32Message', 1, new Sub()); $m->getMapInt32Message()[1]->SetA(36); } public static function setTestMessage2(TestMessage $m) { - $sub = new TestMessage_Sub(); + $sub = new Sub(); $m->setOptionalInt32(-142); $m->setOptionalInt64(-143); @@ -168,7 +168,7 @@ class TestUtil self::appendHelper($m, 'RepeatedString', 'aa'); self::appendHelper($m, 'RepeatedBytes', 'bb'); self::appendHelper($m, 'RepeatedEnum', TestEnum::TWO); - self::appendHelper($m, 'RepeatedMessage', new TestMessage_Sub()); + self::appendHelper($m, 'RepeatedMessage', new Sub()); $m->getRepeatedMessage()[0]->setA(134); self::kvUpdateHelper($m, 'MapInt32Int32', -62, -162); @@ -187,7 +187,7 @@ class TestUtil self::kvUpdateHelper($m, 'MapStringString', 'e', 'ee'); self::kvUpdateHelper($m, 'MapInt32Bytes', 1, 'ff'); self::kvUpdateHelper($m, 'MapInt32Enum', 1, TestEnum::TWO); - self::kvUpdateHelper($m, 'MapInt32Message', 1, new TestMessage_Sub()); + self::kvUpdateHelper($m, 'MapInt32Message', 1, new Sub()); $m->getMapInt32Message()[1]->SetA(136); self::kvUpdateHelper($m, 'MapInt32Int32', -162, -162); @@ -206,7 +206,7 @@ class TestUtil self::kvUpdateHelper($m, 'MapStringString', 'ee', 'ee'); self::kvUpdateHelper($m, 'MapInt32Bytes', 2, 'ff'); self::kvUpdateHelper($m, 'MapInt32Enum', 2, TestEnum::TWO); - self::kvUpdateHelper($m, 'MapInt32Message', 2, new TestMessage_Sub()); + self::kvUpdateHelper($m, 'MapInt32Message', 2, new Sub()); $m->getMapInt32Message()[2]->SetA(136); } diff --git a/php/tests/undefined_test.php b/php/tests/undefined_test.php index dc6b708618..f844457131 100644 --- a/php/tests/undefined_test.php +++ b/php/tests/undefined_test.php @@ -5,7 +5,7 @@ require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\GPBType; use Foo\TestMessage; -use Foo\TestMessage_Sub; +use Foo\TestMessage\Sub; class UndefinedTest extends PHPUnit_Framework_TestCase { @@ -35,7 +35,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testInt32AppendMessageFail() { $arr = new RepeatedField(GPBType::INT32); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -45,7 +45,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::INT32); $arr[] = 0; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -73,7 +73,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testUint32AppendMessageFail() { $arr = new RepeatedField(GPBType::UINT32); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -83,7 +83,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::UINT32); $arr[] = 0; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -111,7 +111,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testInt64AppendMessageFail() { $arr = new RepeatedField(GPBType::INT64); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -121,7 +121,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::INT64); $arr[] = 0; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -149,7 +149,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testUint64AppendMessageFail() { $arr = new RepeatedField(GPBType::UINT64); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -159,7 +159,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::UINT64); $arr[] = 0; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -187,7 +187,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testFloatAppendMessageFail() { $arr = new RepeatedField(GPBType::FLOAT); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -197,7 +197,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::FLOAT); $arr[] = 0.0; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -225,7 +225,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testDoubleAppendMessageFail() { $arr = new RepeatedField(GPBType::DOUBLE); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -235,7 +235,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::DOUBLE); $arr[] = 0.0; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -244,7 +244,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testBoolAppendMessageFail() { $arr = new RepeatedField(GPBType::BOOL); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -254,7 +254,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::BOOL); $arr[] = true; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -263,7 +263,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testStringAppendMessageFail() { $arr = new RepeatedField(GPBType::STRING); - $arr[] = new TestMessage_Sub(); + $arr[] = new Sub(); } /** @@ -273,7 +273,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::STRING); $arr[] = 'abc'; - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -302,7 +302,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase */ public function testMessageAppendIntFail() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); $arr[] = 1; } @@ -311,8 +311,8 @@ class UndefinedTest extends PHPUnit_Framework_TestCase */ public function testMessageSetIntFail() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); - $arr[] = new TestMessage_Sub; + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); + $arr[] = new Sub; $arr[0] = 'abc'; } @@ -321,7 +321,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase */ public function testMessageAppendStringFail() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); $arr[] = 'abc'; } @@ -330,8 +330,8 @@ class UndefinedTest extends PHPUnit_Framework_TestCase */ public function testMessageSetStringFail() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); - $arr[] = new TestMessage_Sub; + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); + $arr[] = new Sub; $arr[0] = 'abc'; } @@ -340,7 +340,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase */ public function testMessageAppendOtherMessageFail() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); $arr[] = new TestMessage; } @@ -349,7 +349,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase */ public function testMessageAppendNullFail() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); $null = null; $arr[] = $null; } @@ -359,8 +359,8 @@ class UndefinedTest extends PHPUnit_Framework_TestCase */ public function testMessageSetNullFail() { - $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); - $arr[] = new TestMessage_Sub(); + $arr = new RepeatedField(GPBType::MESSAGE, Sub::class); + $arr[] = new Sub(); $null = null; $arr[0] = $null; } @@ -397,7 +397,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new RepeatedField(GPBType::INT32); $arr[] = 0; - $arr[new TestMessage_Sub()] = 0; + $arr[new Sub()] = 0; } /** @@ -656,7 +656,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testMessageMergeFromInvalidTypeFail() { $m = new TestMessage(); - $n = new TestMessage_Sub(); + $n = new Sub(); $m->mergeFrom($n); } @@ -684,7 +684,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testInt32SetMessageKeyFail() { $arr = new MapField(GPBType::INT32, GPBType::INT32); - $arr[new TestMessage_Sub()] = 0; + $arr[new Sub()] = 0; } /** @@ -693,7 +693,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testInt32SetMessageValueFail() { $arr = new MapField(GPBType::INT32, GPBType::INT32); - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -720,7 +720,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testUint32SetMessageKeyFail() { $arr = new MapField(GPBType::UINT32, GPBType::UINT32); - $arr[new TestMessage_Sub()] = 0; + $arr[new Sub()] = 0; } /** @@ -729,7 +729,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testUint32SetMessageValueFail() { $arr = new MapField(GPBType::UINT32, GPBType::UINT32); - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -756,7 +756,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testInt64SetMessageKeyFail() { $arr = new MapField(GPBType::INT64, GPBType::INT64); - $arr[new TestMessage_Sub()] = 0; + $arr[new Sub()] = 0; } /** @@ -765,7 +765,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testInt64SetMessageValueFail() { $arr = new MapField(GPBType::INT64, GPBType::INT64); - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -792,7 +792,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testUint64SetMessageKeyFail() { $arr = new MapField(GPBType::UINT64, GPBType::UINT64); - $arr[new TestMessage_Sub()] = 0; + $arr[new Sub()] = 0; } /** @@ -801,7 +801,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testUint64SetMessageValueFail() { $arr = new MapField(GPBType::UINT64, GPBType::UINT64); - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -819,7 +819,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testDoubleSetMessageValueFail() { $arr = new MapField(GPBType::INT64, GPBType::DOUBLE); - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** @@ -828,7 +828,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testBoolSetMessageKeyFail() { $arr = new MapField(GPBType::BOOL, GPBType::BOOL); - $arr[new TestMessage_Sub()] = true; + $arr[new Sub()] = true; } /** @@ -837,7 +837,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testBoolSetMessageValueFail() { $arr = new MapField(GPBType::BOOL, GPBType::BOOL); - $arr[true] = new TestMessage_Sub(); + $arr[true] = new Sub(); } /** @@ -864,7 +864,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testStringSetMessageKeyFail() { $arr = new MapField(GPBType::STRING, GPBType::STRING); - $arr[new TestMessage_Sub()] = 'abc'; + $arr[new Sub()] = 'abc'; } /** @@ -873,7 +873,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase public function testStringSetMessageValueFail() { $arr = new MapField(GPBType::STRING, GPBType::STRING); - $arr['abc'] = new TestMessage_Sub(); + $arr['abc'] = new Sub(); } /** @@ -903,7 +903,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase { $arr = new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class); - $arr[0] = new TestMessage_Sub(); + $arr[0] = new Sub(); } /** diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php index a7760685c7..1e8c4f4286 100644 --- a/php/tests/well_known_test.php +++ b/php/tests/well_known_test.php @@ -14,8 +14,8 @@ use Google\Protobuf\Enum; use Google\Protobuf\EnumValue; use Google\Protobuf\Field; use Google\Protobuf\FieldMask; -use Google\Protobuf\Field_Cardinality; -use Google\Protobuf\Field_Kind; +use Google\Protobuf\Field\Cardinality; +use Google\Protobuf\Field\Kind; use Google\Protobuf\FloatValue; use Google\Protobuf\GPBEmpty; use Google\Protobuf\Int32Value; @@ -206,11 +206,11 @@ class WellKnownTest extends TestBase { { $m = new Field(); - $m->setKind(Field_Kind::TYPE_DOUBLE); - $this->assertSame(Field_Kind::TYPE_DOUBLE, $m->getKind()); + $m->setKind(Kind::TYPE_DOUBLE); + $this->assertSame(Kind::TYPE_DOUBLE, $m->getKind()); - $m->setCardinality(Field_Cardinality::CARDINALITY_OPTIONAL); - $this->assertSame(Field_Cardinality::CARDINALITY_OPTIONAL, $m->getCardinality()); + $m->setCardinality(Cardinality::CARDINALITY_OPTIONAL); + $this->assertSame(Cardinality::CARDINALITY_OPTIONAL, $m->getCardinality()); $m->setNumber(1); $this->assertSame(1, $m->getNumber()); diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 34d0f9efe2..cdb2f50993 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -108,31 +108,40 @@ void GenerateServiceDocComment(io::Printer* printer, void GenerateServiceMethodDocComment(io::Printer* printer, const MethodDescriptor* method); -std::string RenameEmpty(const std::string& name) { - if (name == "Empty") { - return "GPBEmpty"; - } else { - return name; + +std::string ReservedNamePrefix(const string& classname, + const FileDescriptor* file) { + bool is_reserved = false; + + string lower = classname; + transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + + for (int i = 0; i < kReservedNamesSize; i++) { + if (lower == kReservedNames[i]) { + is_reserved = true; + break; + } } -} -std::string MessageFullName(const Descriptor* message, bool is_descriptor) { - if (is_descriptor) { - return StringReplace(message->full_name(), - "google.protobuf", - "google.protobuf.internal", false); - } else { - return message->full_name(); + if (is_reserved) { + if (file->package() == "google.protobuf") { + return "GPB"; + } else { + return "PB"; + } } + + return ""; } -std::string EnumFullName(const EnumDescriptor* envm, bool is_descriptor) { +template +std::string DescriptorFullName(const DescriptorType* desc, bool is_descriptor) { if (is_descriptor) { - return StringReplace(envm->full_name(), + return StringReplace(desc->full_name(), "google.protobuf", "google.protobuf.internal", false); } else { - return envm->full_name(); + return desc->full_name(); } } @@ -144,22 +153,43 @@ std::string ClassNamePrefix(const string& classname, return prefix; } - bool is_reserved = false; + return ReservedNamePrefix(classname, desc->file()); +} + +template +std::string GeneratedClassName(const DescriptorType* desc) { + std::string classname = ClassNamePrefix(desc->name(), desc) + desc->name(); + const Descriptor* containing = desc->containing_type(); + while (containing != NULL) { + classname = ClassNamePrefix(containing->name(), desc) + containing->name() + + '\\' + classname; + containing = containing->containing_type(); + } + return classname; +} + +std::string GeneratedClassName(const ServiceDescriptor* desc) { + std::string classname = desc->name(); + return ClassNamePrefix(classname, desc) + classname; +} +template +std::string LegacyGeneratedClassName(const DescriptorType* desc) { + std::string classname = desc->name(); + const Descriptor* containing = desc->containing_type(); + while (containing != NULL) { + classname = containing->name() + '_' + classname; + containing = containing->containing_type(); + } + return ClassNamePrefix(classname, desc) + classname; +} + +std::string ClassNamePrefix(const string& classname) { string lower = classname; transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (int i = 0; i < kReservedNamesSize; i++) { if (lower == kReservedNames[i]) { - is_reserved = true; - break; - } - } - - if (is_reserved) { - if (desc->file()->package() == "google.protobuf") { - return "GPB"; - } else { return "PB"; } } @@ -195,34 +225,39 @@ std::string ConstantNamePrefix(const string& classname) { } template -std::string NamespacedName(const string& classname, - const DescriptorType* desc, bool is_descriptor) { +std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { if (desc->file()->options().has_php_namespace()) { const string& php_namespace = desc->file()->options().php_namespace(); if (php_namespace != "") { - return php_namespace + '\\' + classname; - } else { - return classname; + return php_namespace; } + return ""; } - if (desc->file()->package() == "") { - return classname; - } else { - return PhpName(desc->file()->package(), is_descriptor) + '\\' + - classname; + if (desc->file()->package() != "") { + return PhpName(desc->file()->package(), is_descriptor); } + return ""; } template std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { string classname = GeneratedClassName(desc); - return NamespacedName(classname, desc, is_descriptor); + string php_namespace = RootPhpNamespace(desc, is_descriptor); + if (php_namespace != "") { + return php_namespace + "\\" + classname; + } + return classname; } -std::string FullClassName(const ServiceDescriptor* desc, bool is_descriptor) { - string classname = GeneratedClassName(desc); - return NamespacedName(classname, desc, is_descriptor); +template +std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) { + string classname = LegacyGeneratedClassName(desc); + string php_namespace = RootPhpNamespace(desc, is_descriptor); + if (php_namespace != "") { + return php_namespace + "\\" + classname; + } + return classname; } std::string PhpName(const std::string& full_name, bool is_descriptor) { @@ -230,20 +265,23 @@ std::string PhpName(const std::string& full_name, bool is_descriptor) { return kDescriptorPackageName; } + std::string segment; std::string result; bool cap_next_letter = true; for (int i = 0; i < full_name.size(); i++) { if ('a' <= full_name[i] && full_name[i] <= 'z' && cap_next_letter) { - result += full_name[i] + ('A' - 'a'); + segment += full_name[i] + ('A' - 'a'); cap_next_letter = false; } else if (full_name[i] == '.') { - result += '\\'; + result += ClassNamePrefix(segment) + segment + '\\'; + segment = ""; cap_next_letter = true; } else { - result += full_name[i]; + segment += full_name[i]; cap_next_letter = false; } } + result += ClassNamePrefix(segment) + segment; return result; } @@ -277,6 +315,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, int start_index = 0; int first_index = proto_file.find_first_of("/", start_index); std::string result = ""; + std::string segment = ""; if (proto_file == kEmptyFile) { return kEmptyMetadataFile; @@ -307,9 +346,9 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, } else { result += "GPBMetadata/"; while (first_index != string::npos) { - result += UnderscoresToCamelCase( + segment = UnderscoresToCamelCase( file_no_suffix.substr(start_index, first_index - start_index), true); - result += "/"; + result += ReservedNamePrefix(segment, file) + segment + "/"; start_index = first_index + 1; first_index = file_no_suffix.find_first_of("/", start_index); } @@ -322,15 +361,16 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, } else { file_name_start += 1; } - result += RenameEmpty(UnderscoresToCamelCase( - file_no_suffix.substr(file_name_start, first_index - file_name_start), true)); + segment = UnderscoresToCamelCase( + file_no_suffix.substr(file_name_start, first_index - file_name_start), true); - return result += ".php"; + return result + ReservedNamePrefix(segment, file) + segment + ".php"; } -std::string GeneratedMessageFileName(const Descriptor* message, +template +std::string GeneratedClassFileName(const DescriptorType* desc, bool is_descriptor) { - std::string result = FullClassName(message, is_descriptor); + std::string result = FullClassName(desc, is_descriptor); for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -339,9 +379,11 @@ std::string GeneratedMessageFileName(const Descriptor* message, return result + ".php"; } -std::string GeneratedEnumFileName(const EnumDescriptor* en, - bool is_descriptor) { - std::string result = FullClassName(en, is_descriptor); +template +std::string LegacyGeneratedClassFileName(const DescriptorType* desc, + bool is_descriptor) { + std::string result = LegacyFullClassName(desc, is_descriptor); + for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -484,10 +526,10 @@ std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor) std::string EnumOrMessageSuffix( const FieldDescriptor* field, bool is_descriptor) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - return ", '" + MessageFullName(field->message_type(), is_descriptor) + "'"; + return ", '" + DescriptorFullName(field->message_type(), is_descriptor) + "'"; } if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - return ", '" + EnumFullName(field->enum_type(), is_descriptor) + "'"; + return ", '" + DescriptorFullName(field->enum_type(), is_descriptor) + "'"; } return ""; } @@ -674,11 +716,11 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { printer->Print( "GPBUtil::checkMessage($var, \\^class_name^::class);\n", - "class_name", FullClassName(field->message_type(), is_descriptor)); + "class_name", LegacyFullClassName(field->message_type(), is_descriptor)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( "GPBUtil::checkEnum($var, \\^class_name^::class);\n", - "class_name", FullClassName(field->enum_type(), is_descriptor)); + "class_name", LegacyFullClassName(field->enum_type(), is_descriptor)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { printer->Print( "GPBUtil::checkString($var, ^utf8^);\n", @@ -734,7 +776,7 @@ void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) { printer->Print( "$pool->addEnum('^name^', " "\\Google\\Protobuf\\Internal\\^class_name^::class)\n", - "name", EnumFullName(en, true), + "name", DescriptorFullName(en, true), "class_name", en->name()); Indent(printer); @@ -766,13 +808,13 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, if (message->options().map_entry()) { return; } - string class_name = name_prefix.empty()? - message->name() : name_prefix + "_" + message->name(); + string class_name = (name_prefix.empty() ? "" : name_prefix + "\\") + + ReservedNamePrefix(message->name(), message->file()) + message->name(); printer->Print( "$pool->addMessage('^message^', " "\\Google\\Protobuf\\Internal\\^class_name^::class)\n", - "message", MessageFullName(message, true), + "message", DescriptorFullName(message, true), "class_name", class_name); Indent(printer); @@ -1001,9 +1043,47 @@ void GenerateMetadataFile(const FileDescriptor* file, printer.Print("}\n\n"); } +template +void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* desc, + bool is_descriptor, + GeneratorContext* generator_context) { + + std::string filename = LegacyGeneratedClassFileName(desc, is_descriptor); + std::unique_ptr output( + generator_context->Open(filename)); + io::Printer printer(output.get(), '^'); + + GenerateHead(file, &printer); + + std::string php_namespace = RootPhpNamespace(desc, is_descriptor); + if (php_namespace != "") { + printer.Print( + "namespace ^name^;\n\n", + "name", php_namespace); + } + std::string newname = FullClassName(desc, is_descriptor); + printer.Print("if (false) {\n"); + Indent(&printer); + printer.Print("/**\n"); + printer.Print(" * This class is deprecated. Use ^new^ instead.\n", + "new", newname); + printer.Print(" * @deprecated\n"); + printer.Print(" */\n"); + printer.Print("class ^old^ {}\n", + "old", LegacyGeneratedClassName(desc)); + Outdent(&printer); + printer.Print("}\n"); + printer.Print("class_exists(^new^::class);\n", + "new", GeneratedClassName(desc)); + printer.Print("@trigger_error('^old^ is deprecated and will be removed in " + "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n", + "old", LegacyFullClassName(desc, is_descriptor), + "fullname", newname); +} + void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, bool is_descriptor, GeneratorContext* generator_context) { - std::string filename = GeneratedEnumFileName(en, is_descriptor); + std::string filename = GeneratedClassFileName(en, is_descriptor); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1013,32 +1093,22 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (file->options().has_php_namespace()) { - const string& php_namespace = file->options().php_namespace(); - if (!php_namespace.empty()) { - printer.Print( - "namespace ^name^;\n\n", - "name", php_namespace); - } - } else if (!file->package().empty()) { + if (lastindex != string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); } - GenerateEnumDocComment(&printer, en, is_descriptor); - if (lastindex != string::npos) { - printer.Print( - "class ^name^\n" - "{\n", - "name", fullname.substr(lastindex + 1)); - } else { - printer.Print( - "class ^name^\n" - "{\n", - "name", fullname); + fullname = fullname.substr(lastindex + 1); } + + GenerateEnumDocComment(&printer, en, is_descriptor); + + printer.Print( + "class ^name^\n" + "{\n", + "name", fullname); Indent(&printer); for (int i = 0; i < en->value_count(); i++) { @@ -1051,6 +1121,17 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, Outdent(&printer); printer.Print("}\n\n"); + + // write legacy file for backwards compatiblity with nested messages and enums + if (en->containing_type() != NULL) { + printer.Print( + "// Adding a class alias for backwards compatibility with the previous class name.\n"); + printer.Print( + "class_alias(^new^::class, \\^old^::class);\n\n", + "new", fullname, + "old", LegacyFullClassName(en, is_descriptor)); + LegacyGenerateClassFile(file, en, is_descriptor, generator_context); + } } void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, @@ -1062,7 +1143,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, return; } - std::string filename = GeneratedMessageFileName(message, is_descriptor); + std::string filename = GeneratedClassFileName(message, is_descriptor); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1072,14 +1153,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (file->options().has_php_namespace()) { - const string& php_namespace = file->options().php_namespace(); - if (!php_namespace.empty()) { - printer.Print( - "namespace ^name^;\n\n", - "name", php_namespace); - } - } else if (!file->package().empty()) { + if (lastindex != string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1089,16 +1163,13 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, GenerateMessageDocComment(&printer, message, is_descriptor); if (lastindex != string::npos) { - printer.Print( - "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n" - "{\n", - "name", fullname.substr(lastindex + 1)); - } else { - printer.Print( - "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n" - "{\n", - "name", fullname); + fullname = fullname.substr(lastindex + 1); } + + printer.Print( + "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n" + "{\n", + "name", fullname); Indent(&printer); // Field and oneof definitions. @@ -1150,6 +1221,17 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, Outdent(&printer); printer.Print("}\n\n"); + // write legacy file for backwards compatiblity with nested messages and enums + if (message->containing_type() != NULL) { + printer.Print( + "// Adding a class alias for backwards compatibility with the previous class name.\n"); + printer.Print( + "class_alias(^new^::class, \\^old^::class);\n\n", + "new", fullname, + "old", LegacyFullClassName(message, is_descriptor)); + LegacyGenerateClassFile(file, message, is_descriptor, generator_context); + } + // Nested messages and enums. for (int i = 0; i < message->nested_type_count(); i++) { GenerateMessageFile(file, message->nested_type(i), is_descriptor, @@ -1174,14 +1256,9 @@ void GenerateServiceFile(const FileDescriptor* file, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (file->options().has_php_namespace()) { - const string& php_namespace = file->options().php_namespace(); - if (!php_namespace.empty()) { - printer.Print( - "namespace ^name^;\n\n", - "name", php_namespace); - } - } else if (!file->package().empty()) { + if (!file->options().php_namespace().empty() || + (!file->options().has_php_namespace() && !file->package().empty()) || + lastindex != string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1337,7 +1414,7 @@ void GenerateMessageDocComment(io::Printer* printer, printer->Print( " * Generated from protobuf message ^messagename^\n" " */\n", - "fullname", EscapePhpdoc(PhpName(message->full_name(), is_descriptor)), + "fullname", EscapePhpdoc(FullClassName(message, is_descriptor)), "messagename", EscapePhpdoc(message->full_name())); } @@ -1413,9 +1490,9 @@ void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, printer->Print("/**\n"); GenerateDocCommentBody(printer, enum_); printer->Print( - " * Protobuf enum ^fullname^\n" + " * Protobuf type ^fullname^\n" " */\n", - "fullname", EscapePhpdoc(PhpName(enum_->full_name(), is_descriptor))); + "fullname", EscapePhpdoc(enum_->full_name())); } void GenerateEnumValueDocComment(io::Printer* printer, @@ -1468,31 +1545,6 @@ bool Generator::Generate(const FileDescriptor* file, const string& parameter, return true; } -std::string GeneratedClassName(const Descriptor* desc) { - std::string classname = desc->name(); - const Descriptor* containing = desc->containing_type(); - while (containing != NULL) { - classname = containing->name() + '_' + classname; - containing = containing->containing_type(); - } - return ClassNamePrefix(classname, desc) + classname; -} - -std::string GeneratedClassName(const EnumDescriptor* desc) { - std::string classname = desc->name(); - const Descriptor* containing = desc->containing_type(); - while (containing != NULL) { - classname = containing->name() + '_' + classname; - containing = containing->containing_type(); - } - return ClassNamePrefix(classname, desc) + classname; -} - -std::string GeneratedClassName(const ServiceDescriptor* desc) { - std::string classname = desc->name(); - return ClassNamePrefix(classname, desc) + classname; -} - } // namespace php } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index 54a95ef523..1e01151130 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -51,16 +51,6 @@ class LIBPROTOC_EXPORT Generator }; -// To skip reserved keywords in php, some generated classname are prefixed. -// Other code generators may need following API to figure out the actual -// classname. -LIBPROTOC_EXPORT std::string GeneratedClassName( - const google::protobuf::Descriptor* desc); -LIBPROTOC_EXPORT std::string GeneratedClassName( - const google::protobuf::EnumDescriptor* desc); -LIBPROTOC_EXPORT std::string GeneratedClassName( - const google::protobuf::ServiceDescriptor* desc); - } // namespace php } // namespace compiler } // namespace protobuf diff --git a/tests.sh b/tests.sh index 5fec74c048..da6072813a 100755 --- a/tests.sh +++ b/tests.sh @@ -107,7 +107,7 @@ build_csharp() { # Check that the protos haven't broken C# codegen. # TODO(jonskeet): Fail if regenerating creates any changes. csharp/generate_protos.sh - + csharp/buildall.sh cd conformance && make test_csharp && cd .. @@ -352,6 +352,7 @@ generate_php_test_proto() { rm -rf generated mkdir generated ../../src/protoc --php_out=generated \ + proto/empty/echo.proto \ proto/test.proto \ proto/test_include.proto \ proto/test_no_namespace.proto \ From dadc95438ff732cb0c1d2961ce7bcf0d99d179b1 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 23 May 2018 18:14:34 -0700 Subject: [PATCH 10/28] Fix array constructor in c extension for compatibility (#4667) In old generated code, the constructor of message doesn't provide a default null to parent's constructor. Previously, in c extesnion, this case was not handled. --- php/ext/google/protobuf/message.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 690128719f..e28e42a152 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -387,9 +387,9 @@ void Message_construct(zval* msg, zval* array_wrapper) { // object. Here, we manually modify it to our message in such a case. PHP_METHOD(Message, __construct) { // Init message with array - zval* array_wrapper; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!", &array_wrapper, - message_type) == FAILURE) { + zval* array_wrapper = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "|a!", &array_wrapper) == FAILURE) { return; } From 6f723a6624de0e0f9b1ae16ae002e678613e07b8 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Fri, 25 May 2018 14:42:41 -0700 Subject: [PATCH 11/28] Always add -std=c++11 for mac (#4684) --- python/setup.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/python/setup.py b/python/setup.py index 9a328cb51c..a9df075e7b 100755 --- a/python/setup.py +++ b/python/setup.py @@ -203,11 +203,9 @@ if __name__ == '__main__': v, _, _ = platform.mac_ver() if v: - v = float('.'.join(v.split('.')[:2])) - if v >= 10.12: - extra_compile_args.append('-std=c++11') + extra_compile_args.append('-std=c++11') elif os.getenv('KOKORO_BUILD_NUMBER') or os.getenv('KOKORO_BUILD_ID'): - extra_compile_args.append('-std=c++11') + extra_compile_args.append('-std=c++11') if warnings_as_errors in sys.argv: extra_compile_args.append('-Werror') From d1af029104e9b594a99209484914b822addb08fa Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Fri, 25 May 2018 14:12:43 -0700 Subject: [PATCH 12/28] Fixed JS parsing of unspecified map keys We need to use a default of 0 when parsing unspecified map keys, instead of failing an assertion. This change was written by Michael Aaron (michaelaaron@google.com) but I am cherry-picking it directly instead of waiting for the next sync of Google-internal changes. --- js/map.js | 15 +++++-- js/maps_test.js | 40 ++++++++++++++++++- js/testbinary.proto | 32 +++++++++++++++ .../protobuf/compiler/js/js_generator.cc | 6 ++- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/js/map.js b/js/map.js index 7b5b2c389d..2fb1483756 100644 --- a/js/map.js +++ b/js/map.js @@ -443,7 +443,8 @@ jspb.Map.prototype.serializeBinary = function( /** * Read one key/value message from the given BinaryReader. Compatible as the * `reader` callback parameter to jspb.BinaryReader.readMessage, to be called - * when a key/value pair submessage is encountered. + * when a key/value pair submessage is encountered. If the Key is undefined, + * we should default it to 0. * @template K, V * @param {!jspb.Map} map * @param {!jspb.BinaryReader} reader @@ -457,12 +458,17 @@ jspb.Map.prototype.serializeBinary = function( * readMessage, in which case the second callback arg form is used. * * @param {?function(V,!jspb.BinaryReader)=} opt_valueReaderCallback - * The BinaryReader parsing callback for type V, if V is a message type. + * The BinaryReader parsing callback for type V, if V is a message type + * + * @param {K=} opt_defaultKey + * The default value for the type of map keys. Accepting map + * entries with unset keys is required for maps to be backwards compatible + * with the repeated message representation described here: goo.gl/zuoLAC * */ jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn, - opt_valueReaderCallback) { - var key = undefined; + opt_valueReaderCallback, opt_defaultKey) { + var key = opt_defaultKey; var value = undefined; while (reader.nextField()) { @@ -470,6 +476,7 @@ jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn, break; } var field = reader.getFieldNumber(); + if (field == 1) { // Key. key = keyReaderFn.call(reader); diff --git a/js/maps_test.js b/js/maps_test.js index e8dd2f219b..e496f446bd 100755 --- a/js/maps_test.js +++ b/js/maps_test.js @@ -35,6 +35,11 @@ goog.require('goog.userAgent'); goog.require('proto.jspb.test.MapValueEnum'); goog.require('proto.jspb.test.MapValueMessage'); goog.require('proto.jspb.test.TestMapFields'); +goog.require('proto.jspb.test.TestMapFieldsOptionalKeys'); +goog.require('proto.jspb.test.MapEntryOptionalKeysStringKey'); +goog.require('proto.jspb.test.MapEntryOptionalKeysInt32Key'); +goog.require('proto.jspb.test.MapEntryOptionalKeysInt64Key'); +goog.require('proto.jspb.test.MapEntryOptionalKeysBoolKey'); // CommonJS-LoadFromFile: test_pb proto.jspb.test goog.require('proto.jspb.test.MapValueMessageNoBinary'); @@ -76,7 +81,7 @@ function toArray(iter) { * Helper: generate test methods for this TestMapFields class. * @param {?} msgInfo * @param {?} submessageCtor - * @param {!string} suffix + * @param {string} suffix */ function makeTests(msgInfo, submessageCtor, suffix) { /** @@ -260,6 +265,39 @@ function makeTests(msgInfo, submessageCtor, suffix) { var decoded = msgInfo.deserializeBinary(serialized); checkMapFields(decoded); }); + /** + * Tests deserialization of undefined map keys go to default values in binary format. + */ + it('testMapDeserializationForUndefinedKeys', function() { + var testMessageOptionalKeys = new proto.jspb.test.TestMapFieldsOptionalKeys(); + var mapEntryStringKey = new proto.jspb.test.MapEntryOptionalKeysStringKey(); + mapEntryStringKey.setValue("a"); + testMessageOptionalKeys.setMapStringString(mapEntryStringKey); + var mapEntryInt32Key = new proto.jspb.test.MapEntryOptionalKeysInt32Key(); + mapEntryInt32Key.setValue("b"); + testMessageOptionalKeys.setMapInt32String(mapEntryInt32Key); + var mapEntryInt64Key = new proto.jspb.test.MapEntryOptionalKeysInt64Key(); + mapEntryInt64Key.setValue("c"); + testMessageOptionalKeys.setMapInt64String(mapEntryInt64Key); + var mapEntryBoolKey = new proto.jspb.test.MapEntryOptionalKeysBoolKey(); + mapEntryBoolKey.setValue("d"); + testMessageOptionalKeys.setMapBoolString(mapEntryBoolKey); + var deserializedMessage = msgInfo.deserializeBinary( + testMessageOptionalKeys.serializeBinary() + ); + checkMapEquals(deserializedMessage.getMapStringStringMap(), [ + ['', 'a'] + ]); + checkMapEquals(deserializedMessage.getMapInt32StringMap(), [ + [0, 'b'] + ]); + checkMapEquals(deserializedMessage.getMapInt64StringMap(), [ + [0, 'c'] + ]); + checkMapEquals(deserializedMessage.getMapBoolStringMap(), [ + [false, 'd'] + ]); + }); } diff --git a/js/testbinary.proto b/js/testbinary.proto index 116f17fb50..ed5bdfc68f 100644 --- a/js/testbinary.proto +++ b/js/testbinary.proto @@ -201,6 +201,38 @@ message TestMapFields { map map_string_testmapfields = 12; } +// These proto are 'mock map' entries to test the above map deserializing with +// undefined keys. Make sure TestMapFieldsOptionalKeys is written to be +// deserialized by TestMapFields +message MapEntryOptionalKeysStringKey { + optional string key = 1; + optional string value = 2; +} + +message MapEntryOptionalKeysInt32Key { + optional int32 key = 1; + optional string value = 2; +} + +message MapEntryOptionalKeysInt64Key { + optional int64 key = 1; + optional string value = 2; +} + +message MapEntryOptionalKeysBoolKey { + optional bool key = 1; + optional string value = 2; +} + +message TestMapFieldsOptionalKeys { + optional MapEntryOptionalKeysStringKey map_string_string = 1; + optional MapEntryOptionalKeysInt32Key map_int32_string= 8; + optional MapEntryOptionalKeysInt64Key map_int64_string = 9; + optional MapEntryOptionalKeysBoolKey map_bool_string = 10; +} + +// End mock-map entries + enum MapValueEnum { MAP_VALUE_FOO = 0; MAP_VALUE_BAR = 1; diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index d8282e4094..b5771f260c 100755 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -2962,8 +2962,12 @@ void Generator::GenerateClassDeserializeBinaryField( if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { printer->Print(", $messageType$.deserializeBinaryFromReader", "messageType", GetMessagePath(options, value_field->message_type())); + } else { + printer->Print(", null"); } - + printer->Print(", $defaultKey$", + "defaultKey", JSFieldDefault(key_field) + ); printer->Print(");\n"); printer->Print(" });\n"); } else { From 5bf35ecca2c2f3863788d0e551a633c42a2b51ff Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Tue, 29 May 2018 10:25:05 -0700 Subject: [PATCH 13/28] Fix php memory leak test (#4692) --- php/ext/google/protobuf/def.c | 1 + php/tests/memory_leak_test.php | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index cb2c72019f..fa33830b93 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -773,6 +773,7 @@ static size_t classname_len_max(const char *fullname, static bool is_reserved(const char *segment, int length) { bool result; char* lower = ALLOC_N(char, length + 1); + memset(lower, 0, length + 1); memcpy(lower, segment, length); int i = 0; while(lower[i]) { diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index 5456919bcf..4e3874b7f1 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -4,11 +4,19 @@ require_once('generated/NoNamespaceEnum.php'); require_once('generated/NoNamespaceMessage.php'); -require_once('generated/NoNamespaceMessage_NestedEnum.php'); +require_once('generated/NoNamespaceMessage/NestedEnum.php'); +require_once('generated/NoNamespaceMessage/NestedMessage.php'); require_once('generated/PrefixEmpty.php'); require_once('generated/PrefixTestPrefix.php'); +require_once('generated/PrefixTestPrefix/PrefixNestedEnum.php'); +require_once('generated/PrefixTestPrefix/PrefixNestedMessage.php'); require_once('generated/TestEmptyNamespace.php'); +require_once('generated/TestEmptyNamespace/NestedEnum.php'); +require_once('generated/TestEmptyNamespace/NestedMessage.php'); require_once('generated/Bar/TestInclude.php'); +require_once('generated/Bar/TestLegacyMessage.php'); +require_once('generated/Bar/TestLegacyMessage/NestedEnum.php'); +require_once('generated/Bar/TestLegacyMessage/NestedMessage.php'); require_once('generated/Foo/PBARRAY.php'); require_once('generated/Foo/PBEmpty.php'); require_once('generated/Foo/TestEnum.php'); @@ -26,12 +34,17 @@ require_once('generated/Foo/TestUnpackedMessage.php'); require_once('generated/Foo/testLowerCaseMessage.php'); require_once('generated/Foo/testLowerCaseEnum.php'); require_once('generated/GPBMetadata/Proto/Test.php'); -require_once('generated/GPBMetadata/Proto/TestEmptyPhpNamespace.php'); +require_once('generated/TestEmptyPhpNamespace.php'); require_once('generated/GPBMetadata/Proto/TestInclude.php'); -require_once('generated/GPBMetadata/Proto/TestNoNamespace.php'); -require_once('generated/GPBMetadata/Proto/TestPhpNamespace.php'); +require_once('generated/TestNoNamespace.php'); +require_once('generated/Metadata/Php/Test/TestPhpNamespace.php'); require_once('generated/GPBMetadata/Proto/TestPrefix.php'); require_once('generated/Php/Test/TestNamespace.php'); +require_once('generated/Php/Test/TestNamespace/PBEmpty.php'); +require_once('generated/Php/Test/TestNamespace/PBEmpty/NestedEnum.php'); +require_once('generated/Php/Test/TestNamespace/PBEmpty/NestedMessage.php'); +require_once('generated/Php/Test/TestNamespace/NestedEnum.php'); +require_once('generated/Php/Test/TestNamespace/NestedMessage.php'); require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; From 9d64d740a142aa705113c1e7a643003857ca8cf0 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Tue, 29 May 2018 14:29:59 -0700 Subject: [PATCH 14/28] Removed duplicate using statement from ReflectionUtil.cs --- csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs index 18a70b80b8..feaeba0ee7 100644 --- a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs +++ b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs @@ -34,10 +34,6 @@ using Google.Protobuf.Compatibility; using System; using System.Reflection; -#if NET35 -using Google.Protobuf.Compatibility; -#endif - namespace Google.Protobuf.Reflection { /// From 397ddf9e5c7876e907ffd42256cb469f340268ef Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Fri, 25 May 2018 15:24:42 -0700 Subject: [PATCH 15/28] Add back GeneratedClassName to public (#4686) These methods are used by grpc --- src/google/protobuf/compiler/php/php_generator.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index 1e01151130..82109ec449 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -49,6 +49,16 @@ class LIBPROTOC_EXPORT Generator GeneratorContext* generator_context, string* error) const; + // To skip reserved keywords in php, some generated classname are prefixed. + // Other code generators may need following API to figure out the actual + // classname. + LIBPROTOC_EXPORT std::string GeneratedClassName( + const google::protobuf::Descriptor* desc); + LIBPROTOC_EXPORT std::string GeneratedClassName( + const google::protobuf::EnumDescriptor* desc); + LIBPROTOC_EXPORT std::string GeneratedClassName( + const google::protobuf::ServiceDescriptor* desc); + }; } // namespace php From 4f5eb100bb2086622b1f3aaec472d83768b68b32 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Tue, 29 May 2018 21:51:54 -0700 Subject: [PATCH 16/28] Move methods out of class (#4697) --- .../protobuf/compiler/php/php_generator.cc | 20 ++++++++++++++---- .../protobuf/compiler/php/php_generator.h | 21 +++++++++---------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index cdb2f50993..a58e1754d2 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -157,7 +157,7 @@ std::string ClassNamePrefix(const string& classname, } template -std::string GeneratedClassName(const DescriptorType* desc) { +std::string GeneratedClassNameImpl(const DescriptorType* desc) { std::string classname = ClassNamePrefix(desc->name(), desc) + desc->name(); const Descriptor* containing = desc->containing_type(); while (containing != NULL) { @@ -168,11 +168,23 @@ std::string GeneratedClassName(const DescriptorType* desc) { return classname; } -std::string GeneratedClassName(const ServiceDescriptor* desc) { +std::string GeneratedClassNameImpl(const ServiceDescriptor* desc) { std::string classname = desc->name(); return ClassNamePrefix(classname, desc) + classname; } +std::string GeneratedClassName(const Descriptor* desc) { + return GeneratedClassNameImpl(desc); +} + +std::string GeneratedClassName(const EnumDescriptor* desc) { + return GeneratedClassNameImpl(desc); +} + +std::string GeneratedClassName(const ServiceDescriptor* desc) { + return GeneratedClassNameImpl(desc); +} + template std::string LegacyGeneratedClassName(const DescriptorType* desc) { std::string classname = desc->name(); @@ -242,7 +254,7 @@ std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { template std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { - string classname = GeneratedClassName(desc); + string classname = GeneratedClassNameImpl(desc); string php_namespace = RootPhpNamespace(desc, is_descriptor); if (php_namespace != "") { return php_namespace + "\\" + classname; @@ -1074,7 +1086,7 @@ void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* d Outdent(&printer); printer.Print("}\n"); printer.Print("class_exists(^new^::class);\n", - "new", GeneratedClassName(desc)); + "new", GeneratedClassNameImpl(desc)); printer.Print("@trigger_error('^old^ is deprecated and will be removed in " "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n", "old", LegacyFullClassName(desc, is_descriptor), diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index 82109ec449..b851d9b4a2 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -48,19 +48,18 @@ class LIBPROTOC_EXPORT Generator const string& parameter, GeneratorContext* generator_context, string* error) const; - - // To skip reserved keywords in php, some generated classname are prefixed. - // Other code generators may need following API to figure out the actual - // classname. - LIBPROTOC_EXPORT std::string GeneratedClassName( - const google::protobuf::Descriptor* desc); - LIBPROTOC_EXPORT std::string GeneratedClassName( - const google::protobuf::EnumDescriptor* desc); - LIBPROTOC_EXPORT std::string GeneratedClassName( - const google::protobuf::ServiceDescriptor* desc); - }; +// To skip reserved keywords in php, some generated classname are prefixed. +// Other code generators may need following API to figure out the actual +// classname. +LIBPROTOC_EXPORT std::string GeneratedClassName( + const google::protobuf::Descriptor* desc); +LIBPROTOC_EXPORT std::string GeneratedClassName( + const google::protobuf::EnumDescriptor* desc); +LIBPROTOC_EXPORT std::string GeneratedClassName( + const google::protobuf::ServiceDescriptor* desc); + } // namespace php } // namespace compiler } // namespace protobuf From 39d2f703b8c9ea58163e38f711a0c6c2d6b49c7c Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 31 May 2018 10:07:28 -0700 Subject: [PATCH 17/28] Require C++11 and pass -std=c++11 This commit updates the Autotools build to require a C++11 compiler and explicitly pass -std=c++11. This seems to be necessary for enabling C++11 support in older compilers. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 08f98d3b68..aec10cface 100644 --- a/configure.ac +++ b/configure.ac @@ -88,7 +88,7 @@ AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[ # Protocol Buffers contains several checks that are intended to be used only # for debugging and which might hurt performance. Most users are probably # end users who don't want these checks, so add -DNDEBUG by default. - CXXFLAGS="$CXXFLAGS -DNDEBUG" + CXXFLAGS="$CXXFLAGS -std=c++11 -DNDEBUG" AC_MSG_RESULT([use default: $PROTOBUF_OPT_FLAG $CXXFLAGS]) ],[ @@ -207,7 +207,7 @@ case "$target_os" in esac AM_CONDITIONAL([OBJC_CONFORMANCE_TEST], [test $OBJC_CONFORMANCE_TEST = 1]) -AX_CXX_COMPILE_STDCXX([11], [noext], [optional]) +AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) # HACK: Make gmock's configure script pick up our copy of CFLAGS and CXXFLAGS, # since the flags added by ACX_CHECK_SUNCC must be used when compiling gmock From adf84b47f9ad7d0f682521d83957c6cab4ab9f56 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Fri, 1 Jun 2018 13:58:09 -0700 Subject: [PATCH 18/28] Updated the change log with changes for 3.6.0 --- CHANGES.txt | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index c7c42916b8..c18c6377d3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,91 @@ +2018-06-01 version 3.6.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Starting from this release, we now require C++11. For those we cannot yet + upgrade to C++11, we will try to keep the 3.5.x branch updated with + critical bug fixes only. If you have any concerns about this, please + comment on issue #2780. + * Moved to C++11 types like std::atomic and std::unique_ptr and away from our + old custom-built equivalents. + * Added support for repeated message fields in lite protos using implicit + weak fields. This is an experimental feature that allows the linker to + strip out more unused messages than previously was possible. + * Fixed SourceCodeInfo for interpreted options and extension range options. + * Fixed always_print_enums_as_ints option for JSON serialization. + * Added support for ignoring unknown enum values when parsing JSON. + * Create std::string in Arena memory. + * Fixed ValidateDateTime to correctly check the day. + * Fixed bug in ZeroCopyStreamByteSink. + * Various other cleanups and fixes. + + Java + * Dropped support for Java 6. + * Added a UTF-8 decoder that uses Unsafe to directly decode a byte buffer. + * Added deprecation annotations to generated code for deprecated oneof + fields. + * Fixed map field serialization in DynamicMessage. + * Cleanup and documentation for Java Lite runtime. + * Various other fixes and cleanups + * Fixed unboxed arraylists to handle an edge case + * Improved performance for copying between unboxed arraylists + * Fixed lite protobuf to avoid Java compiler warnings + * Improved test coverage for lite runtime + * Performance improvements for lite runtime + + Python + * Fixed bytes/string map key incompatibility between C++ and pure-Python + implementations (issue #4029) + * Added __init__.py files to compiler and util subpackages + * Use /MT for all Windows versions + * Fixed an issue affecting the Python-C++ implementation when used with + Cython (issue #2896) + * Various text format fixes + * Various fixes to resolve behavior differences between the pure-Python and + Python-C++ implementations + + PHP + * Added php_metadata_namespace to control the file path of generated metadata + file. + * Changed generated classes of nested message/enum. E.g., Foo.Bar, which + previously generates Foo_Bar, now generates Foo/Bar + * Added array constructor. When creating a message, users can pass a php + array whose content is field name to value pairs into constructor. The + created message will be initialized according to the array. Note that + message field should use a message value instead of a sub-array. + * Various bug fixes. + + Objective-C + * We removed some helper class methods from GPBDictionary to shrink the size + of the library, the functionary is still there, but you may need to do some + specific +alloc / -init… methods instead. + * Minor improvements in the performance of object field getters/setters by + avoiding some memory management overhead. + * Fix a memory leak during the raising of some errors. + * Make header importing completely order independent. + * Small code improvements for things the undefined behaviors compiler option + was flagging. + + Ruby + * Added ruby_package file option to control the module of generated class. + * Various bug fixes. + + Javascript + * Allow setting string to int64 field. + + Csharp + * Unknown fields are now parsed and then sent back on the wire. They can be + discarded at parse time via a CodedInputStream option. + * Movement towards working with .NET 3.5 and Unity + * Expression trees are no longer used + * AOT generics issues in Unity/il2cpp have a workaround (see this commit for + details) + * Floating point values are now compared bitwise (affects NaN value + comparisons) + * The default size limit when parsing is now 2GB rather than 64MB + * MessageParser now supports parsing from a slice of a byte array + * JSON list parsing now accepts null values where the underlying proto + representation does + 2017-12-20 version 3.5.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) Planned Future Changes * Make C++ implementation C++11 only: we plan to require C++11 to build From 9b77e9efe1e07bd4812d16014a1400a32c2676e1 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Fri, 1 Jun 2018 16:33:15 -0700 Subject: [PATCH 19/28] Removed javanano from post_process_dist.sh --- post_process_dist.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post_process_dist.sh b/post_process_dist.sh index eb5f584d76..5b14de6720 100755 --- a/post_process_dist.sh +++ b/post_process_dist.sh @@ -27,7 +27,7 @@ fi set -ex -LANGUAGES="cpp csharp java javanano js objectivec python ruby php all" +LANGUAGES="cpp csharp java js objectivec python ruby php all" BASENAME=`basename $1 .tar.gz` VERSION=${BASENAME:9} From a3f31bf0e2b74a5b29cbde36ee0d45937f76fda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Campam=C3=A1?= Date: Tue, 5 Jun 2018 15:14:19 -0400 Subject: [PATCH 20/28] Update code to work for Xcode 10b1 (#4729) * Update code to work for Xcode 10b * Update README and test scripts to mention that Xcode 7 is no longer supported --- objectivec/DevTools/full_mac_build.sh | 3 +-- objectivec/GPBArray.m | 4 ++-- objectivec/GPBDescriptor.m | 6 +++--- objectivec/GPBDictionary.m | 4 ++-- objectivec/README.md | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh index 42e4105aa8..c673fcba37 100755 --- a/objectivec/DevTools/full_mac_build.sh +++ b/objectivec/DevTools/full_mac_build.sh @@ -244,8 +244,7 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then exit 10 ;; 7.* ) - echo "ERROR: The unittests include Swift code that is now Swift 3.0." 1>&2 - echo "ERROR: Xcode 8.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2 + echo "ERROR: Xcode 7.x no longer supported for building, please use 8.0 or higher." 1>&2 exit 11 ;; 8.0* ) diff --git a/objectivec/GPBArray.m b/objectivec/GPBArray.m index f401631d12..122e0304b3 100644 --- a/objectivec/GPBArray.m +++ b/objectivec/GPBArray.m @@ -2537,12 +2537,12 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) { return [_array countByEnumeratingWithState:state objects:buffer count:len]; } -- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block { +- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(id obj, NSUInteger idx, BOOL *stop))block { [_array enumerateObjectsUsingBlock:block]; } - (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts - usingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block { + usingBlock:(void (NS_NOESCAPE ^)(id obj, NSUInteger idx, BOOL *stop))block { [_array enumerateObjectsWithOptions:opts usingBlock:block]; } diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m index 615d223459..4b39c63b36 100644 --- a/objectivec/GPBDescriptor.m +++ b/objectivec/GPBDescriptor.m @@ -411,7 +411,7 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex, } - (NSString *)name { - return @(name_); + return (NSString * _Nonnull)@(name_); } - (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber { @@ -582,7 +582,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) { } - (NSString *)name { - return @(description_->name); + return (NSString * _Nonnull)@(description_->name); } - (BOOL)isRequired { @@ -998,7 +998,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) { } - (NSString *)singletonName { - return @(description_->singletonName); + return (NSString * _Nonnull)@(description_->singletonName); } - (const char *)singletonNameC { diff --git a/objectivec/GPBDictionary.m b/objectivec/GPBDictionary.m index aa21670aa3..cedf5e549d 100644 --- a/objectivec/GPBDictionary.m +++ b/objectivec/GPBDictionary.m @@ -12102,14 +12102,14 @@ void GPBDictionaryReadEntry(id mapDictionary, } } -- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, +- (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(id key, id obj, BOOL *stop))block { [_dictionary enumerateKeysAndObjectsUsingBlock:block]; } - (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts - usingBlock:(void (^)(id key, + usingBlock:(void (NS_NOESCAPE ^)(id key, id obj, BOOL *stop))block { [_dictionary enumerateKeysAndObjectsWithOptions:opts usingBlock:block]; diff --git a/objectivec/README.md b/objectivec/README.md index 469a61fbe5..a02df33fca 100644 --- a/objectivec/README.md +++ b/objectivec/README.md @@ -13,7 +13,7 @@ Requirements The Objective C implementation requires: - Objective C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X). -- Xcode 7.0 (or later). +- Xcode 8.0 (or later). - The library code does *not* use ARC (for performance reasons), but it all can be called from ARC code. From d6353b489e16c5ff7dde4aa648f142a0d0b24ceb Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 6 Jun 2018 19:04:25 -0700 Subject: [PATCH 21/28] Update php version to 3.6.0 (#4736) --- php/ext/google/protobuf/package.xml | 22 +++++++++++++++++++--- php/ext/google/protobuf/protobuf.h | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index 3a556acf37..28d713f344 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -10,11 +10,11 @@ protobuf-opensource@google.com yes - 2018-03-06 + 2018-06-06 - 3.5.2 - 3.5.2 + 3.6.0 + 3.6.0 stable @@ -229,6 +229,22 @@ GA release. 3-Clause BSD License +G A release. + + + + + 3.6.0 + 3.6.0 + + + stable + stable + + 2018-06-06 + + 3-Clause BSD License + G A release. diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index c15bde2d19..20035ab7ff 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -37,7 +37,7 @@ #include "upb.h" #define PHP_PROTOBUF_EXTNAME "protobuf" -#define PHP_PROTOBUF_VERSION "3.5.2" +#define PHP_PROTOBUF_VERSION "3.6.0" #define MAX_LENGTH_OF_INT64 20 #define SIZEOF_INT64 8 From ce044817c7ba0aea27c3fd8e496635d94d20a755 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Thu, 7 Jun 2018 18:16:44 -0700 Subject: [PATCH 22/28] Use legacy name in php runtime (#4741) * Use legacy name in php runtime Old generated code cannot work with new runtime, because the new runtime assumes new class name for nested message. For details see #4738. * Remove unused method --- .../Google/Protobuf/Internal/Descriptor.php | 14 ++++++ .../Protobuf/Internal/DescriptorPool.php | 2 + .../Protobuf/Internal/EnumDescriptor.php | 14 ++++++ php/src/Google/Protobuf/Internal/GPBUtil.php | 29 +++++++++-- php/src/Google/Protobuf/Internal/MapField.php | 25 +++++++++- .../Protobuf/Internal/RepeatedField.php | 23 ++++++++- php/tests/compatibility_test.sh | 49 +++++++++++++------ 7 files changed, 134 insertions(+), 22 deletions(-) diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php index ee3a8bdec5..21ac5de364 100644 --- a/php/src/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/Google/Protobuf/Internal/Descriptor.php @@ -44,6 +44,7 @@ class Descriptor private $nested_type = []; private $enum_type = []; private $klass; + private $legacy_klass; private $options; private $oneof_decl = []; @@ -151,6 +152,16 @@ class Descriptor return $this->klass; } + public function setLegacyClass($klass) + { + $this->legacy_klass = $klass; + } + + public function getLegacyClass() + { + return $this->legacy_klass; + } + public function setOptions($options) { $this->options = $options; @@ -167,16 +178,19 @@ class Descriptor $message_name_without_package = ""; $classname = ""; + $legacy_classname = ""; $fullname = ""; GPBUtil::getFullClassName( $proto, $containing, $file_proto, $message_name_without_package, + $legacy_classname, $classname, $fullname); $desc->setFullName($fullname); $desc->setClass($classname); + $desc->setLegacyClass($legacy_classname); $desc->setOptions($proto->getOptions()); foreach ($proto->getField() as $field_proto) { diff --git a/php/src/Google/Protobuf/Internal/DescriptorPool.php b/php/src/Google/Protobuf/Internal/DescriptorPool.php index 304c16158e..9b4dcc0115 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorPool.php +++ b/php/src/Google/Protobuf/Internal/DescriptorPool.php @@ -92,6 +92,7 @@ class DescriptorPool $this->proto_to_class[$descriptor->getFullName()] = $descriptor->getClass(); $this->class_to_desc[$descriptor->getClass()] = $descriptor; + $this->class_to_desc[$descriptor->getLegacyClass()] = $descriptor; foreach ($descriptor->getNestedType() as $nested_type) { $this->addDescriptor($nested_type); } @@ -105,6 +106,7 @@ class DescriptorPool $this->proto_to_class[$descriptor->getFullName()] = $descriptor->getClass(); $this->class_to_enum_desc[$descriptor->getClass()] = $descriptor; + $this->class_to_enum_desc[$descriptor->getLegacyClass()] = $descriptor; } public function getDescriptorByClassName($klass) diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptor.php b/php/src/Google/Protobuf/Internal/EnumDescriptor.php index 01649fec4f..82a427670c 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptor.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptor.php @@ -9,6 +9,7 @@ class EnumDescriptor use HasPublicDescriptorTrait; private $klass; + private $legacy_klass; private $full_name; private $value; private $name_to_value; @@ -66,12 +67,23 @@ class EnumDescriptor return $this->klass; } + public function setLegacyClass($klass) + { + $this->legacy_klass = $klass; + } + + public function getLegacyClass() + { + return $this->legacy_klass; + } + public static function buildFromProto($proto, $file_proto, $containing) { $desc = new EnumDescriptor(); $enum_name_without_package = ""; $classname = ""; + $legacy_classname = ""; $fullname = ""; GPBUtil::getFullClassName( $proto, @@ -79,9 +91,11 @@ class EnumDescriptor $file_proto, $enum_name_without_package, $classname, + $legacy_classname, $fullname); $desc->setFullName($fullname); $desc->setClass($classname); + $desc->setLegacyClass($legacy_classname); $values = $proto->getValue(); foreach ($values as $value) { $desc->addValue($value->getNumber(), $value); diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php index 023b07f4d3..ec0bf6bdbe 100644 --- a/php/src/Google/Protobuf/Internal/GPBUtil.php +++ b/php/src/Google/Protobuf/Internal/GPBUtil.php @@ -215,9 +215,10 @@ class GPBUtil "Expect repeated field of different type."); } if ($var->getType() === GPBType::MESSAGE && - $var->getClass() !== $klass) { + $var->getClass() !== $klass && + $var->getLegacyClass() !== $klass) { throw new \Exception( - "Expect repeated field of different message."); + "Expect repeated field of " . $klass . "."); } return $var; } @@ -242,9 +243,10 @@ class GPBUtil throw new \Exception("Expect map field of value type."); } if ($var->getValueType() === GPBType::MESSAGE && - $var->getValueClass() !== $klass) { + $var->getValueClass() !== $klass && + $var->getLegacyValueClass() !== $klass) { throw new \Exception( - "Expect map field of different value message."); + "Expect map field of " . $klass . "."); } return $var; } @@ -299,6 +301,14 @@ class GPBUtil return ""; } + public static function getLegacyClassNameWithoutPackage( + $name, + $file_proto) + { + $classname = implode('_', explode('.', $name)); + return static::getClassNamePrefix($classname, $file_proto) . $classname; + } + public static function getClassNameWithoutPackage( $name, $file_proto) @@ -316,6 +326,7 @@ class GPBUtil $file_proto, &$message_name_without_package, &$classname, + &$legacy_classname, &$fullname) { // Full name needs to start with '.'. @@ -334,21 +345,28 @@ class GPBUtil $class_name_without_package = static::getClassNameWithoutPackage($message_name_without_package, $file_proto); + $legacy_class_name_without_package = + static::getLegacyClassNameWithoutPackage( + $message_name_without_package, $file_proto); $option = $file_proto->getOptions(); if (!is_null($option) && $option->hasPhpNamespace()) { $namespace = $option->getPhpNamespace(); if ($namespace !== "") { $classname = $namespace . "\\" . $class_name_without_package; + $legacy_classname = + $namespace . "\\" . $legacy_class_name_without_package; return; } else { $classname = $class_name_without_package; + $legacy_classname = $legacy_class_name_without_package; return; } } if ($package === "") { $classname = $class_name_without_package; + $legacy_classname = $legacy_class_name_without_package; } else { $parts = array_map('ucwords', explode('.', $package)); foreach ($parts as $i => $part) { @@ -358,6 +376,9 @@ class GPBUtil implode('\\', $parts) . "\\".self::getClassNamePrefix($class_name_without_package,$file_proto). $class_name_without_package; + $legacy_classname = + implode('\\', array_map('ucwords', explode('.', $package))). + "\\".$legacy_class_name_without_package; } } diff --git a/php/src/Google/Protobuf/Internal/MapField.php b/php/src/Google/Protobuf/Internal/MapField.php index 38736dad88..f7d7b71014 100644 --- a/php/src/Google/Protobuf/Internal/MapField.php +++ b/php/src/Google/Protobuf/Internal/MapField.php @@ -58,7 +58,11 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable /** * @ignore */ - private $value_klass; + private $klass; + /** + * @ignore + */ + private $legacy_klass; /** * Constructs an instance of MapField. @@ -75,6 +79,17 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable $this->key_type = $key_type; $this->value_type = $value_type; $this->klass = $klass; + + if ($this->value_type == GPBType::MESSAGE) { + $pool = DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByClassName($klass); + if ($desc == NULL) { + new $klass; // No msg class instance has been created before. + $desc = $pool->getDescriptorByClassName($klass); + } + $this->klass = $desc->getClass(); + $this->legacy_klass = $desc->getLegacyClass(); + } } /** @@ -101,6 +116,14 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable return $this->klass; } + /** + * @ignore + */ + public function getLegacyValueClass() + { + return $this->legacy_klass; + } + /** * Return the element at the given key. * diff --git a/php/src/Google/Protobuf/Internal/RepeatedField.php b/php/src/Google/Protobuf/Internal/RepeatedField.php index 797b3b3a9c..e0ddef5059 100644 --- a/php/src/Google/Protobuf/Internal/RepeatedField.php +++ b/php/src/Google/Protobuf/Internal/RepeatedField.php @@ -59,6 +59,10 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable * @ignore */ private $klass; + /** + * @ignore + */ + private $legacy_klass; /** * Constructs an instance of RepeatedField. @@ -71,7 +75,16 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable { $this->container = []; $this->type = $type; - $this->klass = $klass; + if ($this->type == GPBType::MESSAGE) { + $pool = DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByClassName($klass); + if ($desc == NULL) { + new $klass; // No msg class instance has been created before. + $desc = $pool->getDescriptorByClassName($klass); + } + $this->klass = $desc->getClass(); + $this->legacy_klass = $desc->getLegacyClass(); + } } /** @@ -90,6 +103,14 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable return $this->klass; } + /** + * @ignore + */ + public function getLegacyClass() + { + return $this->legacy_klass; + } + /** * Return the element at the given index. * diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh index 7caa46e7ad..b5b255ea81 100755 --- a/php/tests/compatibility_test.sh +++ b/php/tests/compatibility_test.sh @@ -2,12 +2,14 @@ function use_php() { VERSION=$1 - PHP=`which php` - PHP_CONFIG=`which php-config` - PHPIZE=`which phpize` - ln -sfn "/usr/local/php-${VERSION}/bin/php" $PHP - ln -sfn "/usr/local/php-${VERSION}/bin/php-config" $PHP_CONFIG - ln -sfn "/usr/local/php-${VERSION}/bin/phpize" $PHPIZE + + OLD_PATH=$PATH + OLD_CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH + OLD_C_INCLUDE_PATH=$C_INCLUDE_PATH + + export PATH=/usr/local/php-${VERSION}/bin:$OLD_PATH + export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_CPLUS_INCLUDE_PATH + export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_C_INCLUDE_PATH } function generate_proto() { @@ -18,7 +20,22 @@ function generate_proto() { mkdir generated $PROTOC1 --php_out=generated proto/test_include.proto - $PROTOC2 --php_out=generated proto/test.proto proto/test_no_namespace.proto proto/test_prefix.proto + $PROTOC2 --php_out=generated \ + proto/test.proto \ + proto/test_no_namespace.proto \ + proto/test_prefix.proto \ + proto/test_php_namespace.proto \ + proto/test_empty_php_namespace.proto \ + proto/test_reserved_enum_lower.proto \ + proto/test_reserved_enum_upper.proto \ + proto/test_reserved_enum_value_lower.proto \ + proto/test_reserved_enum_value_upper.proto \ + proto/test_reserved_message_lower.proto \ + proto/test_reserved_message_upper.proto \ + proto/test_service.proto \ + proto/test_service_namespace.proto \ + proto/test_descriptors.proto + pushd ../../src $PROTOC2 --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto popd @@ -52,9 +69,9 @@ cd $(dirname $0) # The old version of protobuf that we are testing compatibility against. case "$1" in - ""|3.3.0) - OLD_VERSION=3.3.0 - OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.3.0/protoc-3.3.0-linux-x86_64.exe + ""|3.5.0) + OLD_VERSION=3.5.0 + OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/$OLD_VERSION/protoc-$OLD_VERSION-linux-x86_64.exe ;; *) echo "[ERROR]: Unknown version number: $1" @@ -81,7 +98,7 @@ git checkout v$OLD_VERSION popd # Build and copy the new runtime -use_php 5.5 +use_php 7.1 pushd ../ext/google/protobuf make clean || true phpize && ./configure && make @@ -99,12 +116,12 @@ chmod +x old_protoc NEW_PROTOC=`pwd`/../../src/protoc OLD_PROTOC=`pwd`/old_protoc cd protobuf/php -cp -r /usr/local/vendor-5.5 vendor -wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit +composer install # Remove implementation detail tests. tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php ) sed -i.bak '/php_implementation_test.php/d' phpunit.xml +sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml for t in "${tests[@]}" do remove_error_test tests/$t @@ -118,7 +135,7 @@ cd tests generate_proto $OLD_PROTOC $OLD_PROTOC ./test.sh pushd .. -phpunit +./vendor/bin/phpunit popd # Test A.2: @@ -127,7 +144,7 @@ popd generate_proto $NEW_PROTOC $OLD_PROTOC ./test.sh pushd .. -phpunit +./vendor/bin/phpunit popd # Test A.3: @@ -136,5 +153,5 @@ popd generate_proto $OLD_PROTOC $NEW_PROTOC ./test.sh pushd .. -phpunit +./vendor/bin/phpunit popd From b0a8220e92ce7eaccb3042efa123e17b4d0719e9 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 14 Jun 2018 16:48:53 -0700 Subject: [PATCH 23/28] Added Kokoro Windows release build config for protoc (#4766) This should make it easy to automatically build 32-bit and 64-bit Windows protoc binaries. --- kokoro/release/protoc/windows/build.bat | 27 +++++++++++++++++++++++ kokoro/release/protoc/windows/release.cfg | 8 +++++++ 2 files changed, 35 insertions(+) create mode 100644 kokoro/release/protoc/windows/build.bat create mode 100644 kokoro/release/protoc/windows/release.cfg diff --git a/kokoro/release/protoc/windows/build.bat b/kokoro/release/protoc/windows/build.bat new file mode 100644 index 0000000000..ae0fa94a10 --- /dev/null +++ b/kokoro/release/protoc/windows/build.bat @@ -0,0 +1,27 @@ +set PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH% +set generator32=Visual Studio 14 +set generator64=Visual Studio 14 Win64 +set vcplatform32=win32 +set vcplatform64=x64 +set configuration=Release + +echo Building protoc +cd github\protobuf + +mkdir build32 +cd build32 +cmake -G "%generator32%" -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_UNICODE=ON ../cmake +msbuild protobuf.sln /p:Platform=%vcplatform32% || goto error +cd .. + +mkdir build64 +cd build64 +cmake -G "%generator64%" -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_UNICODE=ON ../cmake +msbuild protobuf.sln /p:Platform=%vcplatform64% || goto error +cd .. + +goto :EOF + +:error +echo Failed! +exit /b %ERRORLEVEL% diff --git a/kokoro/release/protoc/windows/release.cfg b/kokoro/release/protoc/windows/release.cfg new file mode 100644 index 0000000000..0d0da8f133 --- /dev/null +++ b/kokoro/release/protoc/windows/release.cfg @@ -0,0 +1,8 @@ +# Configuration for Windows protoc release builds +build_file: "protobuf/kokoro/release/protoc/windows/build.bat" + +action { + define_artifacts { + regex: "**/protoc.exe" + } +} From 885be9c9828514595f2f1d24c45aec620b739730 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Mon, 18 Jun 2018 11:38:06 -0700 Subject: [PATCH 24/28] Work around MSVC issue with std::atomic initialization (#4777) * Work around MSVC issue with std::atomic initialization MSVC seems to have a bug where it does not use constant initialization for std::atomic, which ends up causing crashes during initialization. This change introduces a workaround by putting the std::atomic inside a union, which causes the compiler to use constant initialization for it. * Added an AppVeyor test for static linking with MSVC --- appveyor.yml | 8 +++++--- src/google/protobuf/generated_message_util.h | 9 +++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 02e0d31356..9644e066a3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,3 @@ -# Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can -# test more combinations but AppVeyor just takes too long to finish (each -# combination takes ~15mins). platform: - Win64 @@ -14,6 +11,11 @@ environment: BUILD_DLL: ON UNICODE: ON + - language: cpp + image: Visual Studio 2017 + BUILD_DLL: OFF + UNICODE: ON + - language: csharp image: Visual Studio 2017 diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index c26e3e52cf..706df38364 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -335,7 +335,16 @@ struct LIBPROTOBUF_EXPORT SCCInfoBase { kRunning = 1, kUninitialized = -1, // initial state }; +#ifndef _MSC_VER std::atomic visit_status; +#else + // MSVC doesnt make std::atomic constant initialized. This union trick + // makes it so. + union { + int visit_status_to_make_linker_init; + std::atomic visit_status; + }; +#endif int num_deps; void (*init_func)(); // This is followed by an array of num_deps From ad85c3b4a2598670de129015fab03a97edea73bc Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Mon, 18 Jun 2018 14:34:14 -0700 Subject: [PATCH 25/28] Added Kokoro protoc release build for OS X (#4770) This configuration builds both 32-bit and 64-bit binaries for Mac OS X. One thing I had to change was to increase our minimum supported version for 10.7 to 10.9, because 10.9 (Mavericks) appears to be the earliest version supporting C++11. --- kokoro/release/protoc/macos/build.sh | 23 +++++++++++++++++++++++ kokoro/release/protoc/macos/release.cfg | 8 ++++++++ 2 files changed, 31 insertions(+) create mode 100644 kokoro/release/protoc/macos/build.sh create mode 100644 kokoro/release/protoc/macos/release.cfg diff --git a/kokoro/release/protoc/macos/build.sh b/kokoro/release/protoc/macos/build.sh new file mode 100644 index 0000000000..db9d3140db --- /dev/null +++ b/kokoro/release/protoc/macos/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -x +CXXFLAGS_COMMON="-DNDEBUG -mmacosx-version-min=10.9" + +cd github/protobuf +./autogen.sh + +mkdir build32 && cd build32 +export CXXFLAGS="$CXXFLAGS_COMMON -m32" +../configure --disable-shared +make -j4 +file src/protoc +otool -L src/protoc | grep dylib +cd .. + +mkdir build64 && cd build64 +export CXXFLAGS="$CXXFLAGS_COMMON -m64" +../configure --disable-shared +make -j4 +file src/protoc +otool -L src/protoc | grep dylib +cd .. diff --git a/kokoro/release/protoc/macos/release.cfg b/kokoro/release/protoc/macos/release.cfg new file mode 100644 index 0000000000..da903d0316 --- /dev/null +++ b/kokoro/release/protoc/macos/release.cfg @@ -0,0 +1,8 @@ +# Configuration for Mac OSX protoc release builds +build_file: "protobuf/kokoro/release/protoc/macos/build.sh" + +action { + define_artifacts { + regex: "**/protoc" + } +} From b907a03185a3267a3ce0e4456aabf32dcfc54049 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Fri, 22 Jun 2018 10:26:17 -0700 Subject: [PATCH 26/28] Add files to build ruby artifact for mac on kokoro (#4814) * Add files to build ruby artifact for mac on kokoro * Move ruby specific stuff to ruby dir --- kokoro/release/macos/build_artifacts.cfg | 8 +++ kokoro/release/macos/build_artifacts.sh | 19 +++++++ kokoro/release/macos/ruby/ruby_build.sh | 15 +++++ .../macos/ruby/ruby_build_environment.sh | 56 +++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 kokoro/release/macos/build_artifacts.cfg create mode 100755 kokoro/release/macos/build_artifacts.sh create mode 100755 kokoro/release/macos/ruby/ruby_build.sh create mode 100755 kokoro/release/macos/ruby/ruby_build_environment.sh diff --git a/kokoro/release/macos/build_artifacts.cfg b/kokoro/release/macos/build_artifacts.cfg new file mode 100644 index 0000000000..35d36deed4 --- /dev/null +++ b/kokoro/release/macos/build_artifacts.cfg @@ -0,0 +1,8 @@ +# Configuration for Mac OSX release builds +build_file: "protobuf/kokoro/release/macos/build_artifacts.sh" + +action { + define_artifacts { + regex: "github/protobuf/artifacts/**" + } +} diff --git a/kokoro/release/macos/build_artifacts.sh b/kokoro/release/macos/build_artifacts.sh new file mode 100755 index 0000000000..23135ca354 --- /dev/null +++ b/kokoro/release/macos/build_artifacts.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -ex + +# change to repo root +cd $(dirname $0)/../../.. + +# all artifacts come here +mkdir artifacts +export ARTIFACT_DIR=$(pwd)/artifacts + +# ruby environment +bash kokoro/release/macos/ruby/ruby_build_environment.sh + +gem install rubygems-update +update_rubygems + +# build artifacts +bash kokoro/release/macos/ruby/ruby_build.sh diff --git a/kokoro/release/macos/ruby/ruby_build.sh b/kokoro/release/macos/ruby/ruby_build.sh new file mode 100755 index 0000000000..cf6b433d06 --- /dev/null +++ b/kokoro/release/macos/ruby/ruby_build.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Build protoc +if test ! -e src/protoc; then + ./autogen.sh + ./configure + make -j4 +fi + +umask 0022 +pushd ruby +bundle install && bundle exec rake gem:native +ls pkg +mv pkg/* $ARTIFACT_DIR +popd diff --git a/kokoro/release/macos/ruby/ruby_build_environment.sh b/kokoro/release/macos/ruby/ruby_build_environment.sh new file mode 100755 index 0000000000..cc072e5556 --- /dev/null +++ b/kokoro/release/macos/ruby/ruby_build_environment.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +set -ex + +set +ex # rvm script is very verbose and exits with errorcode +source $HOME/.rvm/scripts/rvm +set -e # rvm commands are very verbose +time rvm install 2.5.0 +rvm use 2.5.0 --default +gem install bundler --no-ri --no-doc +rvm osx-ssl-certs status all +rvm osx-ssl-certs update all +set -ex + +rm -rf ~/.rake-compiler + +CROSS_RUBY=$(mktemp tmpfile.XXXXXXXX) + +curl https://raw.githubusercontent.com/rake-compiler/rake-compiler/v1.0.3/tasks/bin/cross-ruby.rake > "$CROSS_RUBY" + +# See https://github.com/grpc/grpc/issues/12161 for verconf.h patch details +patch "$CROSS_RUBY" << EOF +--- cross-ruby.rake 2018-04-10 11:32:16.000000000 -0700 ++++ patched 2018-04-10 11:40:25.000000000 -0700 +@@ -133,8 +133,10 @@ + "--host=#{MINGW_HOST}", + "--target=#{MINGW_TARGET}", + "--build=#{RUBY_BUILD}", +- '--enable-shared', ++ '--enable-static', ++ '--disable-shared', + '--disable-install-doc', ++ '--without-gmp', + '--with-ext=' + ] + +@@ -151,6 +153,7 @@ + # make + file "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/ruby.exe" => ["#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/Makefile"] do |t| + chdir File.dirname(t.prerequisites.first) do ++ sh "test -s verconf.h || rm -f verconf.h" # if verconf.h has size 0, make sure it gets re-built by make + sh MAKE + end + end +EOF + +MAKE="make -j8" + +for v in 2.5.0 2.4.0 2.3.0 2.2.2 2.1.6 2.0.0-p645 ; do + ccache -c + rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" +done + +sed 's/x86_64-darwin-11/universal-darwin/' ~/.rake-compiler/config.yml > "$CROSS_RUBY" +mv "$CROSS_RUBY" ~/.rake-compiler/config.yml + From 56d27530ab573d8c8a9808bff9542ca2e8a9291a Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Fri, 22 Jun 2018 13:00:55 -0700 Subject: [PATCH 27/28] Rename build_artifacts.cfg to release.cfg (#4818) --- kokoro/release/macos/{build_artifacts.cfg => release.cfg} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename kokoro/release/macos/{build_artifacts.cfg => release.cfg} (100%) diff --git a/kokoro/release/macos/build_artifacts.cfg b/kokoro/release/macos/release.cfg similarity index 100% rename from kokoro/release/macos/build_artifacts.cfg rename to kokoro/release/macos/release.cfg From f7ada1280fac4af717d478e6a9765d3f02b418b3 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Mon, 25 Jun 2018 11:14:49 -0700 Subject: [PATCH 28/28] Build ruby gem on kokoro (#4819) * Install rake compiler * Add kokoro config to build ruby gem on linux * Rename from linix to linux * Fix prepare_build.sh name * Clean up * Install bundler * Install bundler * Use c99 in order to build gem on mingw-32 on ruby 2.0.0 See https://github.com/rake-compiler/rake-compiler-dock/issues/4 * Move c99 config to extcofig.rb --- kokoro/release/linux/build_artifacts.sh | 14 ++++++++++++++ kokoro/release/linux/prepare_build.sh | 16 ++++++++++++++++ kokoro/release/linux/release.cfg | 8 ++++++++ kokoro/release/linux/ruby/ruby_build.sh | 15 +++++++++++++++ .../release/linux/ruby/ruby_build_environment.sh | 8 ++++++++ .../release/macos/ruby/ruby_build_environment.sh | 1 + ruby/ext/google/protobuf_c/extconf.rb | 4 +++- 7 files changed, 65 insertions(+), 1 deletion(-) create mode 100755 kokoro/release/linux/build_artifacts.sh create mode 100755 kokoro/release/linux/prepare_build.sh create mode 100644 kokoro/release/linux/release.cfg create mode 100755 kokoro/release/linux/ruby/ruby_build.sh create mode 100755 kokoro/release/linux/ruby/ruby_build_environment.sh diff --git a/kokoro/release/linux/build_artifacts.sh b/kokoro/release/linux/build_artifacts.sh new file mode 100755 index 0000000000..ae7dc813c4 --- /dev/null +++ b/kokoro/release/linux/build_artifacts.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -ex + +# change to repo root +cd $(dirname $0)/../../.. + +source kokoro/release/linux/prepare_build.sh + +# ruby environment +source kokoro/release/linux/ruby/ruby_build_environment.sh + +# build artifacts +bash kokoro/release/linux/ruby/ruby_build.sh diff --git a/kokoro/release/linux/prepare_build.sh b/kokoro/release/linux/prepare_build.sh new file mode 100755 index 0000000000..d3ff87647e --- /dev/null +++ b/kokoro/release/linux/prepare_build.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Move docker's storage location to scratch disk so we don't run out of space. +echo 'DOCKER_OPTS="${DOCKER_OPTS} --graph=/tmpfs/docker"' | sudo tee --append /etc/default/docker +# Use container registry mirror for pulling docker images (should make downloads faster) +# See https://cloud.google.com/container-registry/docs/using-dockerhub-mirroring +echo 'DOCKER_OPTS="${DOCKER_OPTS} --registry-mirror=https://mirror.gcr.io"' | sudo tee --append /etc/default/docker +sudo service docker restart + +# Download Docker images from DockerHub +export DOCKERHUB_ORGANIZATION=grpctesting + +# All artifacts come here +mkdir artifacts +export ARTIFACT_DIR=$(pwd)/artifacts + diff --git a/kokoro/release/linux/release.cfg b/kokoro/release/linux/release.cfg new file mode 100644 index 0000000000..5dae7019d4 --- /dev/null +++ b/kokoro/release/linux/release.cfg @@ -0,0 +1,8 @@ +# Configuration for Linux release builds +build_file: "protobuf/kokoro/release/linux/build_artifacts.sh" + +action { + define_artifacts { + regex: "github/protobuf/artifacts/**" + } +} diff --git a/kokoro/release/linux/ruby/ruby_build.sh b/kokoro/release/linux/ruby/ruby_build.sh new file mode 100755 index 0000000000..cf6b433d06 --- /dev/null +++ b/kokoro/release/linux/ruby/ruby_build.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Build protoc +if test ! -e src/protoc; then + ./autogen.sh + ./configure + make -j4 +fi + +umask 0022 +pushd ruby +bundle install && bundle exec rake gem:native +ls pkg +mv pkg/* $ARTIFACT_DIR +popd diff --git a/kokoro/release/linux/ruby/ruby_build_environment.sh b/kokoro/release/linux/ruby/ruby_build_environment.sh new file mode 100755 index 0000000000..ea04f9055c --- /dev/null +++ b/kokoro/release/linux/ruby/ruby_build_environment.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set +ex +[[ -s /etc/profile.d/rvm.sh ]] && . /etc/profile.d/rvm.sh +set -e # rvm commands are very verbose +rvm --default use ruby-2.4.1 +gem install bundler --update +set -ex diff --git a/kokoro/release/macos/ruby/ruby_build_environment.sh b/kokoro/release/macos/ruby/ruby_build_environment.sh index cc072e5556..e9c619cd1c 100755 --- a/kokoro/release/macos/ruby/ruby_build_environment.sh +++ b/kokoro/release/macos/ruby/ruby_build_environment.sh @@ -7,6 +7,7 @@ source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 rvm use 2.5.0 --default +gem install rake-compiler --no-ri --no-doc gem install bundler --no-ri --no-doc rvm osx-ssl-certs status all rvm osx-ssl-certs update all diff --git a/ruby/ext/google/protobuf_c/extconf.rb b/ruby/ext/google/protobuf_c/extconf.rb index 0886e60708..cc097e1185 100644 --- a/ruby/ext/google/protobuf_c/extconf.rb +++ b/ruby/ext/google/protobuf_c/extconf.rb @@ -2,7 +2,9 @@ require 'mkmf' -$CFLAGS += " -std=c99 -O3 -DNDEBUG" +unless RUBY_PLATFORM =~ /mswin|mingw/ + $CFLAGS += " -std=c99 -O3 -DNDEBUG" +end if RUBY_PLATFORM =~ /linux/