2222use Google \Cloud \Core \TimeTrait ;
2323use Google \Cloud \Spanner \V1 \TypeAnnotationCode ;
2424use Google \Cloud \Spanner \V1 \TypeCode ;
25+ use Google \Protobuf \Internal \DescriptorPool ;
26+ use Google \Protobuf \Internal \Message ;
2527
2628/**
2729 * Manage value mappings between Google Cloud PHP and Cloud Spanner
@@ -43,6 +45,7 @@ class ValueMapper
4345 const TYPE_STRUCT = TypeCode::STRUCT ;
4446 const TYPE_NUMERIC = TypeCode::NUMERIC ;
4547 const TYPE_JSON = TypeCode::JSON ;
48+ const TYPE_PROTO = TypeCode::PROTO ;
4649 const TYPE_PG_NUMERIC = 'pgNumeric ' ;
4750 const TYPE_PG_JSONB = 'pgJsonb ' ;
4851 const TYPE_PG_OID = 'pgOid ' ;
@@ -67,6 +70,7 @@ class ValueMapper
6770 self ::TYPE_PG_JSONB ,
6871 self ::TYPE_PG_OID ,
6972 self ::TYPE_FLOAT32 ,
73+ self ::TYPE_PROTO ,
7074 ];
7175
7276 /*
@@ -366,6 +370,9 @@ private function decodeValue($value, array $type)
366370 }
367371 }
368372
373+ break ;
374+ case self ::TYPE_PROTO :
375+ $ value = new Proto ($ value , $ type ['protoTypeFqn ' ]);
369376 break ;
370377 }
371378
@@ -652,6 +659,7 @@ private function arrayParam($value, ArrayType $arrayObj, $allowMixedArrayType =
652659
653660 // counts the diff data types used inside the array
654661 $ uniqueTypes = [];
662+ $ protoTypeFqn = null ;
655663 $ res = null ;
656664 if ($ value !== null ) {
657665 $ res = [];
@@ -682,6 +690,10 @@ private function arrayParam($value, ArrayType $arrayObj, $allowMixedArrayType =
682690 $ inferredType ['typeAnnotation ' ] = $ type [1 ]['typeAnnotation ' ];
683691 }
684692
693+ if (isset ($ type [1 ]['protoTypeFqn ' ])) {
694+ $ protoTypeFqn = $ type [1 ]['protoTypeFqn ' ];
695+ }
696+
685697 $ inferredTypes [] = $ inferredType ;
686698 }
687699 }
@@ -722,6 +734,9 @@ private function arrayParam($value, ArrayType $arrayObj, $allowMixedArrayType =
722734 $ typeObject = $ nestedDef [1 ];
723735 } else {
724736 $ typeObject = $ this ->typeObject ($ typeCode , $ typeAnnotationCode );
737+ if ($ protoTypeFqn ) {
738+ $ typeObject ['protoTypeFqn ' ] = $ protoTypeFqn ;
739+ }
725740 }
726741
727742 $ type = $ this ->typeObject (
@@ -753,10 +768,13 @@ private function objectParam($value)
753768 ? $ value ->typeAnnotation ()
754769 : null ;
755770
756- return [
757- $ this ->typeObject ($ value ->type (), $ typeAnnotation ),
758- $ value ->formatAsString ()
759- ];
771+ $ typeObject = $ this ->typeObject ($ value ->type (), $ typeAnnotation );
772+
773+ if ($ value instanceof Proto) {
774+ $ typeObject ['protoTypeFqn ' ] = $ value ->getProtoTypeFqn ();
775+ }
776+
777+ return [$ typeObject , $ value ->formatAsString ()];
760778 }
761779
762780 if ($ value instanceof Int64) {
@@ -766,6 +784,20 @@ private function objectParam($value)
766784 ];
767785 }
768786
787+ if ($ value instanceof Message) {
788+ $ fullName = DescriptorPool::getGeneratedPool ()
789+ ->getDescriptorByClassName (get_class ($ value ))
790+ ->getFullName ();
791+ $ typeObject = [
792+ 'code ' => self ::TYPE_PROTO ,
793+ 'protoTypeFqn ' => $ fullName ,
794+ ];
795+ return [
796+ $ typeObject ,
797+ base64_encode ($ value ->serializetoString ())
798+ ];
799+ }
800+
769801 throw new \InvalidArgumentException (sprintf (
770802 'Unrecognized value type %s. ' .
771803 'Please ensure you are using the latest version of google/cloud or google/cloud-spanner. ' ,
0 commit comments