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 b7b72182d5
.
* 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
This commit is contained in:
parent
b625aabbe7
commit
f1911f37f8
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$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)) {
|
||||
return $value;
|
||||
} else {
|
||||
$enum_value =
|
||||
$field->getEnumType()->getValueByName($value);
|
||||
}
|
||||
if (is_integer($value)) {
|
||||
return $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;
|
||||
|
@ -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<KeyType, ValueType> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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]],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user