�����JFIF��XX����������    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222�����"����4���������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,�PG"Z_�4�˷����kjز�Z�,F+��_z�,�© �����zh6�٨�ic�fu������������������������������������#ډb���_�N��?�����������wQ���5-�~�I���8���������������������������������TK<5o�Iv-������������������k�_U_������������������������������~b�M��d��������Ӝ�U�Hh��?]��E�w��Q���k�{��_}qFW7HTՑ��Y��F�����?_�'ϔ��_�Ջt������������������������=||I �����6�έ"�����D���/[�k�9����Y�8������ds|\���Ҿp6�Ҵ���]��.����6���z<�v��@]�i%������������������������$j��~����g��J>��no����pM[me�i$[�����������s�o�ᘨ�˸ nɜG-�ĨU�ycP���3.DB�li�;���������������������hj���x����7Z^�N�h��������N3u{�:j�����x�힞��#M��&��jL P@��_���� P�������������������&��o8��������9������@Sz���6�t7#O�ߋ �����s}Yf�T������lmr����Z)'N��k�۞p�����w\�T���������������ȯ?�8`���O��i{wﭹW�[�r�� ��Q4F�׊������3m&L�=��h3�������z~��#����\�l :�F,j@�� ʱ�wQT����8�"kJO����6�֚l������������������}����R�>ډK���]��y����&����p�}b������;N�1�m�r$����|��7�>e�@���B�TM*-i�H��g�D�)� E�m�|�ؘbҗ�a���Ҿ����������������t4�����o���G��*oCN�rP���Q��@z,|?W[0���������:�n,j���WiE��W������$~/�hp\��?��{(�0���+�Y8rΟ�+����>S-S���������������VN;���}�s?.����� w��9��˟<���Mq4�Wv'������{)0�1mB����V����W[��������8�/<� �%���wT^�5���b��)iM� p�g�N�&ݝ������������VO~��q���u���9��� ����!��J27�����$����O-���! �:���%H��� ـ�������y�ΠM=t{!S�� �oK8�������t<����è��������:a��������[������ա�H���~��w��Qz`�p����o�^ ������Q��n����� �,uu�C��$ ^���,�������8�#��:�6��e�|~�����������!�3��3.�\0�����q��o�4`.|� ����y�Q�`~;�d�ׯ,��O�Zw�������`73�v�܋�<�����Ȏ�� ـ4k��5�K�a�u�=9Yd��$>x�A�&�� j0� ���vF��� Y���|�y��� ~�6�@c��1vOp��������Ig�����4��l�OD�����L����� R���c���j�_�uX�6��3?nk��Wy�f;^*B� ��@���~a�`��Eu�������+�����6�L��.ü>��}y���}_�O�6�͐�:�Yr���G�X��kG������l^w����������~㒶sy���Iu�!���� W ��X��N�7BV��O��!X�2����wvG�R�f�T#�����t�/?���%8�^�W�aT����G�cL�M���I��(J����1~�8�?aT ���]����AS�E��(��*E}� 2������#I/�׍qz��^t�̔���������b�Yz4x����t�){ OH�����+(E��A&�N�������XT��o��"�XC����'���)}�J�z�p� ����~5�}�^����+�6����w��c��Q�|�Lp�d�H��}�(�.|����k��c4^�����"�����Z?ȕ ��a<�������L�!0�39C� �Eu�����C�F�Ew�ç ;�n?�*o���B�8�bʝ���'#Rqf����M}7����]�������s2tcS{�\icTx;�\��7K���P������ʇ Z O-��~�������c>"��?��������P�����E��O�8��@�8��G��Q�g�a�Վ���󁶠��䧘��_%#r�>�����1�z�a���eb��qcP��ѵ��n���#L��� =��׀t� L�7�`�����V����A{�C:�g���e@�����w1 Xp�3�c3�ġ�������p��M"'-�@n4���fG���B3�DJ�8[Jo�ߐ���gK)ƛ��$���� �������8�3�����+���� �����6�ʻ���� ���S�kI�*KZlT _`�������?��K�����QK�d���������B`�s}�>���`������*�>��,*@J�d�oF*�����弝��O}�k��s��]��y�ߘ�������c1G�V���<=�7��7����6��q�PT��tXԀ�!9*4�4Tހ���3XΛex�46�������Y��D ����� ����BdemDa����\�_l,����G�/���֌7���Y�](�xTt^%�GE�����4�}bT����ڹ�����;��Y)���B�Q��u��>J/J ���⮶.�XԄ��j�ݳ������+E��d ���r�5�_D�����1 ���o�� �B�x�΢�#����<��W�����8���R6�@���g�M�.��� dr�D��>(otU��@�x=��~v���2� ӣ�d�oBd�����3�eO�6�㣷����������ݜ�6��6Y��Qz`����S��{���\P��~z m5{J/L��1������<�e�ͅPu���b�]�ϔ��������'�������f�b� Zpw��c`"��i���BD@:)ִ�:�]��h���v�E��w���T�l�������P����"Ju�}��وV ��J��G6��. J/�Qgl߭�e�����@�z�Zev2u����)]կ���������7x�������s�M�-<ɯ�c��r��v�����@��$�ޮ}lk���a����'����>x��O\�Z������Fu>������ck#��&:��`�$��ai�>2Δ����l���oF[h�������lE�ܺ�Π���k:)���`������� $[6�����9�����kOw�\|�����8}������ބ:��񶐕��������I�A1/���=�2[�,�!��.}gN#�u����b���� ~���������݊��}34q�����d�E��L��������c��$���"�[q�U�硬g^��%B ��z���r�p�������J�ru%v\h�����1Y�ne`������ǥ:g����pQM~�^��Xi� ��`S�:V2������9.�P���V������?B�k�� ��������AEvw%�_�9C�Q����wKekP�ؠ�\������;Io d�{ ߞo�c1eP�����\� `����E=���@K<�Y��������eڼ�J����w����{av�F�'�M�@��������������/J��+9p����|]���������Iw &`���8���&�M�hg���[�{�������Xj���%��Ӓ�������������������$��(�����ʹN�������<>�I���RY�����K2�NPlL�ɀ�)��&e��������B+ь����(������������������� � �JTx����_?EZ� }@���� 6�U���뙢ط�z��dWI��n` D����噥�[��uV��"�G&�����Ú����2�g�}&m���������������������?ċ���"����Om#�������������������������� ��{���������������������ON��"S�X���Ne��ysQ���@�������������Fn��Vg�����dX�~nj����������������������]J�<�K]:����FW���b�������62����������=��5f����JKw����bf�X������������������������55��~J �%^�������:�-�QIE��P��v�nZum� z � ~ə ���� ���ة����;�f��\v�������g�8�1��f2�������������������������4;�V���ǔ�)�������������������9���1\������������������������������c��v�/'Ƞ�w������������������$�4�R-��t����������������������������������� e�6�/�ġ �̕Ecy�J���u�B���<�W�ַ~�w[B1L۲�-JS΂�{���΃�������������������������������������������A��20�c#���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@���� 0!1@AP"#2Q`$3V�%45a6�FRUq����� ������^7ׅ,$n��������+��F�`��2X'��0vM��p�L=�������5��8������u�p~���.�`r�����\����O��,ư�0oS ��_�M�����l���4�kv\JSd���x���SW�<��Ae�IX����������$I���w�:S���y���›R��9�Q[���,�5�;�@]�%���u�@ *ro�lbI �� ��+���%m:�͇ZV�����u�̉����θau<�fc�.����{�4Ա� �Q����*�Sm��8\ujqs]{kN���)qO�y�_*dJ�b�7���yQqI&9�ԌK!�M}�R�;�������S�T���1���i[U�ɵz�]��U)V�S6���3$K{��ߊ<�(� E]Զ[ǼENg�����'�\?#)Dkf��J���o��v���'�%ƞ�&K�u��!��b�35LX�Ϸ��63$K�a�;�9>,R��W��3�3� d�JeTYE.Mϧ��-�o�j3+y��y^�c�������VO�9NV\nd�1 ��!͕_)a�v;����թ�M�lWR1��)El��P;��yوÏ�u 3�k�5Pr6<�⒲l�!˞*��u־�n�!�l:����UNW ��%��Chx8vL'��X�@��*��)���̮��ˍ��� ����D-M�+J�U�kvK����+�x8��cY������?�Ԡ��~3mo��|�u@[XeY�C�\Kp�x8�oC�C�&����N�~3-H���� ��MX�s�u<`���~"WL��$8ξ��3���a�)|:@�m�\���^�`�@ҷ)�5p+��6���p�%i)P M���ngc�����#0Aruz���RL+xSS?���ʮ}()#�t��mˇ!��0}}y����<�e� �-ή�Ԩ��X������ MF���ԙ~l L.3���}�V뽺�v������멬��Nl�)�2����^�Iq��a��M��qG��T�����c3#������3U�Ǎ���}��לS�|qa��ڃ�+���-��2�f����/��bz��ڐ�� �ݼ[2�ç����k�X�2�* �Z�d���J�G����M*9W���s{��w���T��x��y,�in�O�v��]���n����P�$��JB@=4�OTI�n��e�22a\����q�d���%�$��(���:���: /*�K[PR�fr\nڙdN���F�n�$�4��[�� U�zƶ����� �mʋ���,�ao�u 3�z� �x��Kn����\[��VFmbE;�_U��&V�Gg�]L�۪&#n%�$ɯ��dG���D�TI=�%+AB�Ru#��b4�1�»x�cs�YzڙJG��f��Il���d�eF'T� iA��T���uC�$����Y��H?����[!G`}���ͪ� �纤Hv\������j�Ex�K���!���OiƸ�Yj�+u-<���'q����uN�*�r\��+�]���<�wOZ.fp�ێ��,-*)V?j-kÊ#�`�r��dV����(�ݽBk�����G�ƛk�QmUڗe��Z���f}|����8�8��a���i��3'J�����~G_�^���d�8w������ R�`(�~�.��u���l�s+g�bv���W���lGc}��u���afE~1�Ue������Z�0�8�=e�� f@/�jqEKQQ�J���oN��J���W5~M>$6�Lt�;$ʳ{���^��6�{����v6���ķܰg�V�cnn �~z�x�«�,2�u�?cE+Ș�H؎�%�Za�)���X>uW�Tz�Nyo����s���FQƤ��$��*�&�LLXL)�1�" L��eO��ɟ�9=���:t��Z���c��Ž���Y?�ӭV�wv�~,Y��r�ۗ�|�y��GaF�����C�����.�+� ���v1���fήJ�����]�S��T��B��n5sW}y�$��~z�'�c ��8 ��� ,! �p��VN�S��N�N�q��y8z˱�A��4��*��'������2n<�s���^ǧ˭P�Jޮɏ�U�G�L�J�*#��<�V��t7�8����TĜ>��i}K%,���)[��z�21z ?�N�i�n1?T�I�R#��m-�����������������1����lA�`��fT5+��ܐ�c�q՝��ʐ��,���3�f2U�եmab��#ŠdQ�y>\��)�SLY����w#��.���ʑ�f��� ,"+�w�~�N�'�c�O�3F�������N<���)j��&��,-� �љ���֊�_�zS���TǦ����w�>��?�������n��U仆�V���e�����0���$�C�d���rP �m�׈e�Xm�Vu� �L��.�bֹ��� �[Դaզ���*��\y�8�Է:�Ez\�0�Kq�C b��̘��cө���Q��=0Y��s�N��S.����3.���O�o:���#���v7�[#߫ ��5�܎�L���Er4���9n��COWlG�^��0k�%<���ZB���aB_���������'=��{i�v�l�$�uC���mƎҝ{�c㱼�y]���W�i ��ߧc��m�H� m�"�"�����;Y�ߝ�Z�Ǔ�����:S#��|}�y�,/k�Ld� TA�(�AI$+I3��;Y*���Z��}|��ӧO��d�v��..#:n��f>�>���ȶI�TX��� 8��y����"d�R�|�)0���=���n4��6ⲑ�+��r<�O�܂~zh�z����7ܓ�HH�Ga롏���nCo�>������a ���~]���R���̲c?�6(�q�;5%� |�uj�~z8R�=X��I�V=�|{v�Gj\gc��q����z�؋%M�ߍ����1y��#��@f^���^�>N������#x#۹��6�Y~�?�dfPO��{��P�4��V��u1E1J �*|���%����JN��`eWu�zk M6���q t[�� ��g�G���v��WIG��u_ft����5�j�"�Y�:T��ɐ���*�;� e5���4����q$C��2d�}���� _S�L#m�Yp��O�.�C�;��c����Hi#֩%+) �Ӎ��ƲV���SYź��g |���tj��3�8���r|���V��1#;.SQ�A[���S������#���`n�+���$��$�I �P\[�@�s��(�ED�z���P��])8�G#��0B��[ى��X�II�q<��9�~[Z멜�Z�⊔IWU&A>�P~�#��dp<�?����7���c��'~���5 ��+$���lx@�M�dm��n<=e�dyX��?{�|Aef ,|n3�<~z�ƃ�uۧ�����P��Y,�ӥQ�*g�#먙R�\���;T��i,��[9Qi歉����c>]9�� ��"�c��P�� �Md?٥��If�ت�u��k��/����F��9�c*9��Ǎ:�ØF���z�n*�@|I�ށ9����N3{'��[�'ͬ�Ҳ4��#}��!�V� Fu��,�,mTIk���v C�7v���B�6k�T9��1�*l� '~��ƞF��lU��'�M ����][ΩũJ_�{�i�I�n��$����L�� j��O�dx�����kza۪��#�E��Cl����x˘�o�����V���ɞ�ljr��)�/,�߬h�L��#��^��L�ф�,íMƁe�̩�NB�L�����iL����q�}��(��q��6IçJ$�W�E$��:������=#����(�K�B����zђ <��K(�N�۫K�w��^O{!����)��H���>x�������lx�?>Պ�+�>�W���,Ly!_�D���Ō�l���Q�!�[ �S����J��1��Ɛ�Y}��b,+�Lo�x�ɓ)����=�y�oh�@�꥟/��I��ѭ=��P�y9��� �ۍYӘ�e+�p�Jnϱ?V\SO%�(�t� ���=?MR�[Ș�����d�/ ��n�l��B�7j� ��!�;ӥ�/�[-���A�>��dN�sLj ��,ɪv��=1c�.SQ�O3�U���ƀ�ܽ�E����������̻��9G�ϷD�7(�}��Ävӌ\��y�_0[w ���<΍>����a_��[0+�L��F.�޺��f�>oN�T����q;���y\��bՃ��y�jH�<|q-eɏ�_?_9+P���Hp$�����[ux�K w�Mw��N�ی'$Y2�=��q���KB��P��~�������Yul:�[<����F1�2�O���5=d����]Y�sw:���Ϯ���E��j,_Q��X��z`H1,#II ��d�wr��P˂@�ZJV����y$�\y�{}��^~���[:N����ߌ�U�������O��d�����ؾe��${p>G��3c���Ė�lʌ�� ת��[��`ϱ�-W����dg�I��ig2��� ��}s ��ؤ(%#sS@���~���3�X�nRG�~\jc3�v��ӍL��M[JB�T��s3}��j�Nʖ��W����;7���ç?=X�F=-�=����q�ߚ���#���='�c��7���ڑW�I(O+=:uxq�������������e2�zi+�kuG�R��������0�&e�n���iT^J����~\jy���p'dtG��s����O��3����9* �b#Ɋ�� p������[Bws�T�>d4�ۧs���nv�n���U���_�~,�v����ƜJ1��s�� �QIz���)�(lv8M���U=�;����56��G���s#�K���MP�=��LvyGd��}�VwWBF�'�à �?MH�U�g2�� ����!�p�7Q��j��ڴ����=��j�u��� Jn�A s���uM������e��Ɔ�Ҕ�!)�'��8Ϣ�ٔ���ޝ(��Vp���צ֖d=�IC�J�Ǡ{q������kԭ�߸���i��@K����u�|�p=..�*+����x�����z[Aqġ#s2a�Ɗ���RR�)*HRsi�~�a &f��M��P����-K�L@��Z��Xy�'x�{}��Zm+���:�)�) IJ�-i�u���� ���ܒH��'��L(7�y�GӜq���� j��� 6ߌg1�g�o���,kر���tY�?W,���p���e���f�OQS��!K�۟cҒA�|ս�j�>��=⬒��˧L[�� �߿2JaB~R��u�:��Q�] �0H~���]�7��Ƽ�I���(�}��cq '�ήET���q�?f�ab���ӥvr� �)o��-Q��_'����ᴎo��K������;��V���o��%���~OK ����*��b�f:���-ťIR��`B�5!RB@���ï�� �u �̯e\�_U�_������� g�ES��3��������QT��a�����x����U<~�c?�*�#]�MW,[8O�a�x��]�1bC|踤�P��lw5V%�)�{t�<��d��5���0i�XSU��m:��Z�┵�i�"��1�^B�-��P�hJ��&)O��*�D��c�W��vM��)����}���P��ܗ-q����\mmζZ-l@�}��a��E�6��F�@��&Sg@���ݚ�M����� ȹ 4����#p�\H����dYDo�H���"��\��..R�B�H�z_�/5˘����6��KhJR��P�mƶi�m���3��,#c�co��q�a)*P�t����R�m�k�7x�D�E�\Y�閣_X�<���~�)���c[[�BP����6�Yq���S��0����%_����;��Àv�~�| VS؇ ��'O0��F0��\���U�-�d@�����7�SJ*z��3n��y��P����O����������m�~�P�3|Y��ʉr#�C�<�G~�.,! ���bqx���h~0=��!ǫ�jy����l��O,�[B��~��|9��ٱ����Xly�#�i�B��g%�S��������tˋ���e���ې��\[d�t)��.+u�|1 ������#�~Oj����hS�%��i.�~X���I�H�m��0n���c�1uE�q��cF�RF�o���7� �O�ꮧ� ���ۛ{��ʛi5�rw?׌#Qn�TW��~?y$��m\�\o����%W� ?=>S�N@�� �Ʈ���R����N�)�r"C�:��:����� �����#��qb��Y�. �6[��2K����2u�Ǧ�HYR��Q�MV��� �G�$��Q+.>�����nNH��q�^��� ����q��mM��V��D�+�-�#*�U�̒ ���p욳��u:�������IB���m����PV@O���r[b= �� ��1U�E��_Nm�yKbN�O���U�}�the�`�|6֮P>�\2�P�V���I�D�i�P�O;�9�r�mAHG�W�S]��J*�_�G��+kP�2����Ka�Z���H�'K�x�W�MZ%�O�YD�Rc+o��?�q��Ghm��d�S�oh�\�D�|:W������UA�Qc yT�q��������~^�H��/��#p�CZ���T�I�1�ӏT����4��"�ČZ�����}��`w�#�*,ʹ�� ��0�i��課�Om�*�da��^gJ݅{���l�e9uF#T�ֲ��̲�ٞC"�q���ߍ ոޑ�o#�XZTp����@ o�8��(jd��xw�]�,f���`~��|,s��^����f�1���t��|��m�򸄭/ctr��5s��7�9Q�4�H1꠲BB@�l9@���C�����+�wp�xu�£Yc�9��?`@#�o�mH�s2��)�=��2�.�l����jg�9$�Y�S�%*L������R�Y������7Z���,*=�䷘$�������arm�o�ϰ���UW.|�r�uf����IGw�t����Zwo��~5 ��YյhO+=8fF�)�W�7�L9lM�̘·Y���֘YLf�큹�pRF���99.A �"wz��=E\Z���'a� 2��Ǚ�#;�'}�G���*��l��^"q��+2FQ� hj��kŦ��${���ޮ-�T�٭cf�|�3#~�RJ����t��$b�(R��(����r���dx� >U b�&9,>���%E\� Ά�e�$��'�q't��*�א���ެ�b��-|d���SB�O�O��$�R+�H�)�܎�K��1m`;�J�2�Y~9��O�g8=vqD`K[�F)k�[���1m޼c��n���]s�k�z$@��)!I �x՝"v��9=�ZA=`Ɠi �:�E��)`�7��vI��}d�YI�_ �o�:ob���o ���3Q��&D&�2=�� �Ά��;>�h����y.*ⅥS������Ӭ�+q&����j|UƧ�����}���J0��WW< ۋS�)jQR�j���Ư��rN)�Gű�4Ѷ(�S)Ǣ�8��i��W52���No˓� ۍ%�5brOn�L�;�n��\G����=�^U�dI���8$�&���h��'���+�(������cȁ߫k�l��S^���cƗjԌE�ꭔ��gF���Ȓ��@���}O���*;e�v�WV���YJ\�]X'5��ղ�k�F��b 6R�o՜m��i N�i�����>J����?��lPm�U��}>_Z&�KK��q�r��I�D�Չ~�q�3fL�:S�e>���E���-G���{L�6p�e,8��������QI��h��a�Xa��U�A'���ʂ���s�+טIjP�-��y�8ۈZ?J$��W�P� ��R�s�]��|�l(�ԓ��sƊi��o(��S0���Y� 8�T97.�����WiL��c�~�dxc�E|�2!�X�K�Ƙਫ਼�$((�6�~|d9u+�qd�^3�89��Y�6L�.I�����?���iI�q���9�)O/뚅����O���X��X�V��ZF[�یgQ�L��K1���RҖr@v�#��X�l��F���Нy�S�8�7�kF!A��sM���^rkp�jP�DyS$N���q���nxҍ!U�f�!eh�i�2�m����`�Y�I�9r�6� �TF���C}/�y�^���Η���5d�'��9A-��J��>{�_l+�`��A���[�'��յ�ϛ#w:݅�%��X�}�&�PSt�Q�"�-��\縵�/����$Ɨh�Xb�*�y��BS����;W�ջ_mc�����vt?2}1�;qS�d�d~u:2k5�2�R�~�z+|HE!)�Ǟl��7`��0�<�,�2*���Hl-��x�^����'_TV�gZA�'j� ^�2Ϊ��N7t�����?w�� �x1��f��Iz�C-Ȗ��K�^q�;���-W�DvT�7��8�Z�������� hK�(P:��Q- �8�n�Z���܃e貾�<�1�YT<�,�����"�6{�/ �?�͟��|1�:�#g��W�>$����d��J��d�B���=��jf[��%rE^��il:��B���x���Sּ�1հ��,�=��*�7 fcG��#q� �eh?��2�7�����,�!7x��6�n�LC�4x��},Geǝ�tC.��vS �F�43��zz\��;QYC,6����~;RYS/6���|2���5���v��T��i����������mlv��������&� �nRh^ejR�LG�f���? �ۉҬܦƩ��|��Ȱ����>3����!v��i�ʯ�>�v��オ�X3e���_1z�Kȗ\<������!�8���V��]��?b�k41�Re��T�q��mz��TiOʦ�Z��Xq���L������q"+���2ۨ��8}�&N7XU7Ap�d�X��~�׿��&4e�o�F��� �H�����O���č�c�� 懴�6���͉��+)��v;j��ݷ�� �UV�� i��� j���Y9GdÒJ1��詞�����V?h��l�����l�cGs�ځ�������y�Ac������\V3�? �� ܙg�>qH�S,�E�W�[�㺨�uch�⍸�O�}���a��>�q�6�n6�����N6�q��������N� ���! 1AQaq�0@����"2BRb�#Pr���3C`��Scst���$4D���%Td���� ?�����N����a��3��m���C���w��������xA�m�q�m����m������$����4n淿t'��C"w��zU=D�\R+w�p+Y�T�&�պ@��ƃ��3ޯ?�Aﶂ��aŘ���@-�����Q�=���9D��ռ�ѻ@��M�V��P��܅�G5�f�Y<�u=,EC)�<�Fy'�"�&�չ�X~f��l�KԆV��?�� �W�N����=(� �;���{�r����ٌ�Y���h{�١������jW����P���Tc�����X�K�r��}���w�R��%��?���E��m�� �Y�q|����\lEE4����r���}�lsI�Y������f�$�=�d�yO����p�����yBj8jU�o�/�S��?�U��*������ˍ�0�������u�q�m [�?f����a�� )Q�>����6#������� ?����0UQ����,IX���(6ڵ[�DI�MNލ�c&���υ�j\��X�R|,4��� j������T�hA�e��^���d���b<����n�� �즇�=!���3�^�`j�h�ȓr��jẕ�c�,ٞX����-����a�ﶔ���#�$��]w�O��Ӫ�1y%��L�Y<�wg#�ǝ�̗`�x�xa�t�w��»1���o7o5��>�m뭛C���Uƃߜ}�C���y1Xνm�F8�jI���]����H���ۺиE@I�i;r�8ӭ�����V�F�Շ| ��&?�3|x�B�MuS�Ge�=Ӕ�#BE5G������Y!z��_e��q�р/W>|-�Ci߇�t�1ޯќd�R3�u��g�=0 5��[?�#͏��q�cf���H��{ ?u�=?�?ǯ���}Z��z���hmΔ�BFTW�����<�q��(v� ��!��z���iW]*�J�V�z��gX֧A�q�&��/w���u�gYӘa���; �i=����g:��?2�dž6�ى�k�4�>�Pxs����}������G�9���3 ���)gG�R<>r h�$��'nc�h�P��Bj��J�ҧH� -��N1���N��?��~��}-q!=��_2hc�M��l�vY%UE�@|�v����M2�.Y[|y�"Eï��K�ZF,�ɯ?,q�?v�M 80jx�"�;�9vk�����+ ֧�� �ȺU��?�%�vcV��mA�6��Qg^M�����A}�3�nl� QRN�l8�kkn�'�����(��M�7m9و�q���%ޟ���*h$Zk"��$�9��: �?U8�Sl��,,|ɒ��xH(ѷ����Gn�/Q�4�P��G�%��Ա8�N��!� �&�7�;���eKM7�4��9R/%����l�c>�x;������>��C�:�����t��h?aKX�bhe�ᜋ^�$�Iհ �hr7%F$�E��Fd���t��5���+�(M6�t����Ü�UU|zW�=a�Ts�Tg������dqP�Q����b'�m���1{|Y����X�N��b �P~��F^F:����k6�"�j!�� �I�r�`��1&�-$�Bevk:y���#y�w��I0��x��=D�4��tU���P�ZH��ڠ底taP��6����b>�xa�����Q�#� WeF��ŮNj�p�J* mQ�N�����*I�-*�ȩ�F�g�3 �5��V�ʊ�ɮ�a��5F���O@{���NX��?����H�]3��1�Ri_u��������ѕ�� ����0��� F��~��:60�p�͈�S��qX#a�5>���`�o&+�<2�D����: �������ڝ�$�nP���*)�N�|y�Ej�F�5ټ�e���ihy�Z �>���k�bH�a�v��h�-#���!�Po=@k̆IEN��@��}Ll?j�O������߭�ʞ���Q|A07x���wt!xf���I2?Z��<ץ�T���cU�j��]���陎Ltl �}5�ϓ��$�,��O�mˊ�;�@O��jE��j(�ا,��LX���LO���Ц�90�O �.����a��nA���7������j4 ��W��_ٓ���zW�jcB������y՗+EM�)d���N�g6�y1_x��p�$Lv�:��9�"z��p���ʙ$��^��JԼ*�ϭ����o���=x�Lj�6�J��u82�A�H�3$�ٕ@�=Vv�]�'�qEz�;I˼��)��=��ɯ���x �/�W(V���p�����$ �m�������u�����񶤑Oqˎ�T����r��㠚x�sr�GC��byp�G��1ߠ�w e�8�$⿄����/�M{*}��W�]˷.�CK\�ުx���/$�WP�w���r� |i���&�}�{�X� �>��$-��l���?-z���g����lΆ���(F���h�vS*���b���߲ڡn,|)mrH[���a�3�ר�[1��3o_�U�3�TC�$��(�=�)0�kgP���� ��u�^=��4 �WYCҸ:��vQ�ר�X�à��tk�m,�t*��^�,�}D*�� �"(�I��9R����>`�`��[~Q]�#af��i6l��8���6�:,s�s�N6�j"�A4���IuQ��6E,�GnH��zS�HO�uk�5$�I�4��ؤ�Q9�@��C����wp��BGv[]�u�Ov����0I4���\��y�����Q�Ѹ��~>Z��8�T��a��q�ޣ;z��a���/��S��I:�ܫ_�|������>=Z����8:�S��U�I�J��"IY���8%b8���H��:�QO�6�;7�I�S��J��ҌAά3��>c���E+&jf$eC+�z�;��V����� �r���ʺ������my�e���aQ�f&��6�ND���.:��NT�vm�<- u���ǝ\MvZY�N�NT��-A�>jr!S��n�O 1�3�Ns�%�3D@���`������ܟ 1�^c<���� �a�ɽ�̲�Xë#�w�|y�cW�=�9I*H8�p�^(4���՗�k��arOcW�tO�\�ƍR��8����'�K���I�Q�����?5�>[�}��yU�ײ -h��=��% q�ThG�2�)���"ו3]�!kB��*p�FDl�A���,�eEi�H�f�Ps�����5�H:�Փ~�H�0Dت�D�I����h�F3�������c��2���E��9�H��5�zԑ�ʚ�i�X�=:m�xg�hd(�v����׊�9iS��O��d@0ڽ���:�p�5�h-��t�&���X�q�ӕ,��ie�|���7A�2���O%P��E��htj��Y1��w�Ѓ!����  ���� ࢽ��My�7�\�a�@�ţ�J ��4�Ȼ�F�@o�̒?4�wx��)��]�P��~�����u�����5�����7X ��9��^ܩ�U;Iꭆ 5 �������eK2�7(�{|��Y׎ �V��\"���Z�1� Z�����}��(�Ǝ"�1S���_�vE30>���p;� ΝD��%x�W�?W?v����o�^V�i�d��r[��/&>�~`�9Wh��y�;���R���� ;;ɮT��?����r$�g1�K����A��C��c��K��l:�'��3 c�ﳯ*"t8�~l��)���m��+U,z��`(��>yJ�?����h>��]��v��ЍG*�{`��;y]��I�T� ;c��NU�fo¾h���/$���|NS���1�S�"�H��V���T���4��uhǜ�]�v;���5�͠x��'C\�SBpl���h}�N����� A�Bx���%��ޭ�l��/����T��w�ʽ]D�=����K���ž�r㻠l4�S�O?=�k �M:� ��c�C�a�#ha���)�ѐxc�s���gP�iG���{+���x���Q���I= �� z��ԫ+ �8"�k�ñ�j=|����c ��y��CF��/���*9ж�h{ �?4�o� ��k�m�Q�N�x��;�Y��4膚�a�w?�6�>�e]�����Q�r�:����g�,i"�����ԩA��*M�<�G��b�if��l^M��5�� �Ҩ�{����6J��ZJ�����P�*�����Y���ݛu�_4�9�I8�7���������,^ToR���m4�H��?�N�S�ѕw��/S��甍�@�9H�S�T��t�ƻ���ʒU��*{Xs�@����f������֒Li�K{H�w^���������Ϥm�tq���s� ���ք��f:��o~s��g�r��ט� �S�ѱC�e]�x���a��) ���(b-$(�j>�7q�B?ӕ�F��hV25r[7 Y� }L�R��}����*sg+��x�r�2�U=�*'WS��ZDW]�WǞ�<��叓���{�$�9Ou4��y�90-�1�'*D`�c�^o?(�9��u���ݐ��'PI&� f�Jݮ�������:wS����jfP1F:X �H�9dԯ����˝[�_54 �}*;@�ܨ�� ð�yn�T���?�ןd�#���4rG�ͨ��H�1�|-#���Mr�S3��G�3�����)�.᧏3v�z֑��r����$G"�`j �1t��x0<Ɔ�Wh6�y�6��,œ�Ga��gA����y��b��)���h�D��ß�_�m��ü �gG;��e�v��ݝ�nQ� ��C����-�*��o���y�a��M��I�>�<���]obD��"�:���G�A��-\%LT�8���c�)��+y76���o�Q�#*{�(F�⽕�y����=���rW�\p���۩�c���A���^e6��K������ʐ�cVf5$�'->���ՉN"���F�"�UQ@�f��Gb~��#�&�M=��8�ט�JNu9��D��[̤�s�o�~������� G��9T�tW^g5y$b��Y'��س�Ǵ�=��U-2 #�MC�t(�i� �lj�@Q 5�̣i�*�O����s�x�K�f��}\��M{E�V�{�υ��Ƈ�����);�H����I��fe�Lȣr�2��>��W��I�Ȃ6������i��k�� �5�YOxȺ����>��Y�f5'��|��H+��98pj�n�.O�y�������jY��~��i�w'������l�;�s�2��Y��:'lg�ꥴ)o#'Sa�a�K��Z� �m��}�`169�n���"���x��I ��*+� }F<��cГ���F�P�������ֹ*�PqX�x۩��,� ��N�� �4<-����%����:��7����W���u�`����� $�?�I��&����o��o��`v�>��P��"��l���4��5'�Z�gE���8���?��[�X�7(��.Q�-��*���ތL@̲����v��.5���[��=�t\+�CNܛ��,g�SQnH����}*F�G16���&:�t��4ُ"A��̣��$�b �|����#rs��a�����T�� ]�<�j��B�S�('$�ɻ� �wP;�/�n��?�ݜ��x�F��yUn�~mL*-�������Xf�wd^�a�}��f�,=t�׵i�.2/wpN�Ep8�OР���•��R�FJ� 55TZ��T �ɭ�<��]��/�0�r�@�f��V��V����Nz�G��^���7hZi����k��3�,kN�e|�vg�1{9]_i��X5y7� 8e]�U����'�-2,���e"����]ot�I��Y_��n�(JҼ��1�O ]bXc���Nu�No��pS���Q_���_�?i�~�x h5d'�(qw52] ��'ޤ�q��o1�R!���`ywy�A4u���h<קy���\[~�4�\ X�Wt/� 6�����n�F�a8��f���z �3$�t(���q��q�x��^�XWeN'p<-v�!�{�(>ӽDP7��ո0�y)�e$ٕv�Ih'Q�EA�m*�H��RI��=:��� ���4牢) �%_iN�ݧ�l]� �Nt���G��H�L��� ɱ�g<���1V�,�J~�ٹ�"K��Q�� 9�HS�9�?@��k����r�;we݁�]I�!{ �@�G�[�"��`���J:�n]�{�cA�E����V��ʆ���#��U9�6����j�#Y�m\��q�e4h�B�7��C�������d<�?J����1g:ٳ���=Y���D�p�ц� ׈ǔ��1�]26؜oS�'��9�V�FVu�P�h�9�xc�oq�X��p�o�5��Ա5$�9W�V(�[Ak�aY錎qf;�'�[�|���b�6�Ck��)��#a#a˙��8���=äh�4��2��C��4tm^ �n'c����]GQ$[Wҿ��i���vN�{Fu ��1�gx��1┷���N�m��{j-,��x�� Ūm�ЧS�[�s���Gna���䑴�� x�p 8<������97�Q���ϴ�v�aϚG��Rt�Һ׈�f^\r��WH�JU�7Z���y)�vg=����n��4�_)y��D'y�6�]�c�5̪��\� �PF�k����&�c;��cq�$~T�7j ���nç]�<�g ":�to�t}�159�<�/�8������m�b�K#g'I'.W������6��I/��>v��\�MN��g���m�A�yQL�4u�Lj�j9��#44�t��l^�}L����n��R��!��t��±]��r��h6ٍ>�yҏ�N��fU�� ���� Fm@�8}�/u��jb9������he:A�y�ծw��GpΧh�5����l}�3p468��)U��d��c����;Us/�֔�YX�1�O2��uq�s��`hwg�r~�{ R��mhN��؎*q 42�*th��>�#���E����#��Hv�O����q�}������6�e��\�,Wk�#���X��b>��p}�դ��3���T5��†��6��[��@��P�y*n��|'f�֧>�lư΂�̺����SU�'*�q�p�_S�����M�� '��c�6������m�� ySʨ;M��r���Ƌ�m�Kxo,���Gm�P��A�G�:��i��w�9�}M(�^�V��$ǒ�ѽ�9���|���� �a����J�SQ�a���r�B;����}���ٻ֢�2�%U���c�#�g���N�a�ݕ�'�v�[�OY'��3L�3�;,p�]@�S��{ls��X�'���c�jw��k'a�.��}�}&�� �dP�*�bK=ɍ!����;3n�gΊU�ߴmt�'*{,=SzfD� A��ko~�G�aoq�_mi}#�m�������P�Xhύ�����mxǍ�΂���巿zf��Q���c���|kc�����?���W��Y�$���_Lv����l߶��c���`?����l�j�ݲˏ!V��6����U�Ђ(A���4y)H���p�Z_�x��>���e���R��$�/�`^'3qˏ�-&Q�=?��CFVR �D�fV�9��{�8g�������n�h�(P"��6�[�D���< E�����~0<@�`�G�6����Hг�cc�� �c�K.5��D��d�B���`?�XQ��2��ٿyqo&+�1^� DW�0�ꊩ���G�#��Q�nL3��c���������/��x ��1�1�[y�x�პCW��C�c�UĨ80�m�e�4.{�m��u���I=��f�����0QRls9���f���������9���~f�����Ǩ��a�"@�8���ȁ�Q����#c�ic������G��$���G���r/$W�(��W���V�"��m�7�[m�A�m����bo��D� j����۳� l���^�k�h׽����� ��#� iXn�v��eT�k�a�^Y�4�BN���ĕ���0������� !01@Q"2AaPq3BR�������?�����@4�Q�����T3,���㺠�W�[=JK�Ϟ���2�r^7��vc�:�9 �E�ߴ�w�S#d���Ix��u��:��Hp��9E!�� V 2;73|F��9Y���*ʬ�F��D����u&���y؟��^EA��A��(ɩ���^��GV:ݜDy�`��Jr29ܾ�㝉��[���E;Fzx��YG��U�e�Y�C���� ����v-tx����I�sם�Ę�q��Eb�+P\ :>�i�C'�;�����k|z�رn�y]�#ǿb��Q��������w�����(�r|ӹs��[�D��2v-%��@;�8<a���[\o[ϧw��I!��*0�krs)�[�J9^��ʜ��p1)� "��/_>��o��<1����A�E�y^�C��`�x1'ܣn�p��s`l���fQ��):�l����b>�Me�jH^?�kl3(�z:���1ŠK&?Q�~�{�ٺ�h�y���/�[��V�|6��}�KbX����mn[-��7�5q�94�������dm���c^���h� X��5��<�eޘ>G���-�}�دB�ޟ� ��|�rt�M��V+�]�c?�-#ڛ��^ǂ}���Lkr���O��u�>�-D�ry� D?:ޞ�U��ǜ�7�V��?瓮�"�#���r��չģVR;�n���/_� ؉v�ݶe5d�b9��/O��009�G���5n�W����JpA�*�r9�>�1��.[t���s�F���nQ� V 77R�]�ɫ8����_0<՜�IF�u(v��4��F�k�3��E)��N:��yڮe��P�`�1}�$WS��J�SQ�N�j��ٺ��޵�#l���ј(�5=��5�lǏmoW�v-�1����v,W�mn��߀$x�<����v�j(����c]��@#��1������Ǔ���o'��u+����;G�#�޸��v-lη��/(`i⣍Pm^����ԯ̾9Z��F��������n��1��� ��]�[��)�'�������:�֪�W��FC����� �B9،!?���]��V��A�Վ�M��b�w��G F>_DȬ0¤�#�QR�[V��kz���m�w�"��9ZG�7'[��=�Q����j8R?�zf�\a�=��O�U����*oB�A�|G���2�54 �p��.w7� �� ���&������ξxGHp� B%��$g�����t�Џ򤵍z���HN�u�Я�-�'4��0���;_���3������� !01"@AQa2Pq#3BR�������?����ʩca��en��^��8���<�u#��m*08r��y�N"�<�Ѳ0��@\�p��� �����Kv�D��J8�Fҽ� �f�Y��-m�ybX�NP����}�!*8t(�OqѢ��Q�wW�K��ZD��Δ^e��!� ��B�K��p~�����e*l}z#9ң�k���q#�Ft�o��S�R����-�w�!�S���Ӥß|M�l޶V��!eˈ�8Y���c�ЮM2��tk���� ������J�fS����Ö*i/2�����n]�k�\���|4yX�8��U�P.���Ы[���l��@"�t�<������5�lF���vU�����W��W��;�b�cД^6[#7@vU�xgZv��F�6��Q,K�v��� �+Ъ��n��Ǣ��Ft���8��0��c�@�!�Zq s�v�t�;#](B��-�nῃ~���3g������5�J�%���O������n�kB�ĺ�.r��+���#�N$?�q�/�s�6��p��a����a��J/��M�8��6�ܰ"�*������ɗud"\w���aT(����[��F��U՛����RT�b���n�*��6���O��SJ�.�ij<�v�MT��R\c��5l�sZB>F��<7�;EA��{��E���Ö��1U/�#��d1�a�n.1ě����0�ʾR�h��|�R��Ao�3�m3 ��%�� ���28Q�� ��y��φ���H�To�7�lW>����#i`�q���c����a��� �m,B�-j����݋�'mR1Ήt�>��V��p���s�0IbI�C.���1R�ea�����]H�6�����������4B>��o��](��$B���m�����a�!=���?�B� K�Ǿ+�Ծ"�n���K��*��+��[T#�{�E�J�S����Q�����s�5�:�U�\wĐ�f�3����܆&�)�����I���Ԇw��E T�lrTf6Q|R�h:��[K�� �z��c֧�G�C��%\��_�a��84��HcO�bi��ؖV��7H �)*ģK~Xhչ0��4?�0��� �E<���}3���#���u�?�� ��|g�S�6ꊤ�|�I#Hڛ� �ա��w�X��9��7���Ŀ%�SL��y6č��|�F�a 8���b���$�sק�h���b9RAu7�˨p�Č�_\*w��묦��F ����4D~�f����|(�"m���NK��i�S�>�$d7SlA��/�²����SL��|6N�}���S�˯���g��]6��; �#�.��<���q'Q�1|KQ$�����񛩶"�$r�b:���N8�w@��8$�� �AjfG|~�9F ���Y��ʺ��Bwؒ������M:I岎�G��`s�YV5����6��A �b:�W���G�q%l�����F��H���7�������Fsv7���k�� 403WebShell
403Webshell
Server IP : 77.37.55.151  /  Your IP : 216.73.216.99
Web Server : LiteSpeed
System : Linux lt-bnk-web922.main-hosting.eu 4.18.0-553.70.1.lve.el8.x86_64 #1 SMP Wed Aug 20 14:42:18 UTC 2025 x86_64
User : u970350538 ( 970350538)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/./go/pkg/mod/github.com/gogo/protobuf@v1.3.2/proto/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/./go/pkg/mod/github.com/gogo/protobuf@v1.3.2/proto//table_marshal.go
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors.  All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package proto

import (
	"errors"
	"fmt"
	"math"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"unicode/utf8"
)

// a sizer takes a pointer to a field and the size of its tag, computes the size of
// the encoded data.
type sizer func(pointer, int) int

// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),
// marshals the field to the end of the slice, returns the slice and error (if any).
type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)

// marshalInfo is the information used for marshaling a message.
type marshalInfo struct {
	typ          reflect.Type
	fields       []*marshalFieldInfo
	unrecognized field                      // offset of XXX_unrecognized
	extensions   field                      // offset of XXX_InternalExtensions
	v1extensions field                      // offset of XXX_extensions
	sizecache    field                      // offset of XXX_sizecache
	initialized  int32                      // 0 -- only typ is set, 1 -- fully initialized
	messageset   bool                       // uses message set wire format
	hasmarshaler bool                       // has custom marshaler
	sync.RWMutex                            // protect extElems map, also for initialization
	extElems     map[int32]*marshalElemInfo // info of extension elements

	hassizer      bool // has custom sizer
	hasprotosizer bool // has custom protosizer

	bytesExtensions field // offset of XXX_extensions where the field type is []byte
}

// marshalFieldInfo is the information used for marshaling a field of a message.
type marshalFieldInfo struct {
	field      field
	wiretag    uint64 // tag in wire format
	tagsize    int    // size of tag in wire format
	sizer      sizer
	marshaler  marshaler
	isPointer  bool
	required   bool                              // field is required
	name       string                            // name of the field, for error reporting
	oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements
}

// marshalElemInfo is the information used for marshaling an extension or oneof element.
type marshalElemInfo struct {
	wiretag   uint64 // tag in wire format
	tagsize   int    // size of tag in wire format
	sizer     sizer
	marshaler marshaler
	isptr     bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
}

var (
	marshalInfoMap  = map[reflect.Type]*marshalInfo{}
	marshalInfoLock sync.Mutex

	uint8SliceType = reflect.TypeOf(([]uint8)(nil)).Kind()
)

// getMarshalInfo returns the information to marshal a given type of message.
// The info it returns may not necessarily initialized.
// t is the type of the message (NOT the pointer to it).
func getMarshalInfo(t reflect.Type) *marshalInfo {
	marshalInfoLock.Lock()
	u, ok := marshalInfoMap[t]
	if !ok {
		u = &marshalInfo{typ: t}
		marshalInfoMap[t] = u
	}
	marshalInfoLock.Unlock()
	return u
}

// Size is the entry point from generated code,
// and should be ONLY called by generated code.
// It computes the size of encoded data of msg.
// a is a pointer to a place to store cached marshal info.
func (a *InternalMessageInfo) Size(msg Message) int {
	u := getMessageMarshalInfo(msg, a)
	ptr := toPointer(&msg)
	if ptr.isNil() {
		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
		// so it satisfies the interface, and msg == nil wouldn't
		// catch it. We don't want crash in this case.
		return 0
	}
	return u.size(ptr)
}

// Marshal is the entry point from generated code,
// and should be ONLY called by generated code.
// It marshals msg to the end of b.
// a is a pointer to a place to store cached marshal info.
func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) {
	u := getMessageMarshalInfo(msg, a)
	ptr := toPointer(&msg)
	if ptr.isNil() {
		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
		// so it satisfies the interface, and msg == nil wouldn't
		// catch it. We don't want crash in this case.
		return b, ErrNil
	}
	return u.marshal(b, ptr, deterministic)
}

func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo {
	// u := a.marshal, but atomically.
	// We use an atomic here to ensure memory consistency.
	u := atomicLoadMarshalInfo(&a.marshal)
	if u == nil {
		// Get marshal information from type of message.
		t := reflect.ValueOf(msg).Type()
		if t.Kind() != reflect.Ptr {
			panic(fmt.Sprintf("cannot handle non-pointer message type %v", t))
		}
		u = getMarshalInfo(t.Elem())
		// Store it in the cache for later users.
		// a.marshal = u, but atomically.
		atomicStoreMarshalInfo(&a.marshal, u)
	}
	return u
}

// size is the main function to compute the size of the encoded data of a message.
// ptr is the pointer to the message.
func (u *marshalInfo) size(ptr pointer) int {
	if atomic.LoadInt32(&u.initialized) == 0 {
		u.computeMarshalInfo()
	}

	// If the message can marshal itself, let it do it, for compatibility.
	// NOTE: This is not efficient.
	if u.hasmarshaler {
		// Uses the message's Size method if available
		if u.hassizer {
			s := ptr.asPointerTo(u.typ).Interface().(Sizer)
			return s.Size()
		}
		// Uses the message's ProtoSize method if available
		if u.hasprotosizer {
			s := ptr.asPointerTo(u.typ).Interface().(ProtoSizer)
			return s.ProtoSize()
		}

		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
		b, _ := m.Marshal()
		return len(b)
	}

	n := 0
	for _, f := range u.fields {
		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
			// nil pointer always marshals to nothing
			continue
		}
		n += f.sizer(ptr.offset(f.field), f.tagsize)
	}
	if u.extensions.IsValid() {
		e := ptr.offset(u.extensions).toExtensions()
		if u.messageset {
			n += u.sizeMessageSet(e)
		} else {
			n += u.sizeExtensions(e)
		}
	}
	if u.v1extensions.IsValid() {
		m := *ptr.offset(u.v1extensions).toOldExtensions()
		n += u.sizeV1Extensions(m)
	}
	if u.bytesExtensions.IsValid() {
		s := *ptr.offset(u.bytesExtensions).toBytes()
		n += len(s)
	}
	if u.unrecognized.IsValid() {
		s := *ptr.offset(u.unrecognized).toBytes()
		n += len(s)
	}

	// cache the result for use in marshal
	if u.sizecache.IsValid() {
		atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n))
	}
	return n
}

// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),
// fall back to compute the size.
func (u *marshalInfo) cachedsize(ptr pointer) int {
	if u.sizecache.IsValid() {
		return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32()))
	}
	return u.size(ptr)
}

// marshal is the main function to marshal a message. It takes a byte slice and appends
// the encoded data to the end of the slice, returns the slice and error (if any).
// ptr is the pointer to the message.
// If deterministic is true, map is marshaled in deterministic order.
func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) {
	if atomic.LoadInt32(&u.initialized) == 0 {
		u.computeMarshalInfo()
	}

	// If the message can marshal itself, let it do it, for compatibility.
	// NOTE: This is not efficient.
	if u.hasmarshaler {
		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
		b1, err := m.Marshal()
		b = append(b, b1...)
		return b, err
	}

	var err, errLater error
	// The old marshaler encodes extensions at beginning.
	if u.extensions.IsValid() {
		e := ptr.offset(u.extensions).toExtensions()
		if u.messageset {
			b, err = u.appendMessageSet(b, e, deterministic)
		} else {
			b, err = u.appendExtensions(b, e, deterministic)
		}
		if err != nil {
			return b, err
		}
	}
	if u.v1extensions.IsValid() {
		m := *ptr.offset(u.v1extensions).toOldExtensions()
		b, err = u.appendV1Extensions(b, m, deterministic)
		if err != nil {
			return b, err
		}
	}
	if u.bytesExtensions.IsValid() {
		s := *ptr.offset(u.bytesExtensions).toBytes()
		b = append(b, s...)
	}
	for _, f := range u.fields {
		if f.required {
			if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
				// Required field is not set.
				// We record the error but keep going, to give a complete marshaling.
				if errLater == nil {
					errLater = &RequiredNotSetError{f.name}
				}
				continue
			}
		}
		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
			// nil pointer always marshals to nothing
			continue
		}
		b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic)
		if err != nil {
			if err1, ok := err.(*RequiredNotSetError); ok {
				// Required field in submessage is not set.
				// We record the error but keep going, to give a complete marshaling.
				if errLater == nil {
					errLater = &RequiredNotSetError{f.name + "." + err1.field}
				}
				continue
			}
			if err == errRepeatedHasNil {
				err = errors.New("proto: repeated field " + f.name + " has nil element")
			}
			if err == errInvalidUTF8 {
				if errLater == nil {
					fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
					errLater = &invalidUTF8Error{fullName}
				}
				continue
			}
			return b, err
		}
	}
	if u.unrecognized.IsValid() {
		s := *ptr.offset(u.unrecognized).toBytes()
		b = append(b, s...)
	}
	return b, errLater
}

// computeMarshalInfo initializes the marshal info.
func (u *marshalInfo) computeMarshalInfo() {
	u.Lock()
	defer u.Unlock()
	if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock
		return
	}

	t := u.typ
	u.unrecognized = invalidField
	u.extensions = invalidField
	u.v1extensions = invalidField
	u.bytesExtensions = invalidField
	u.sizecache = invalidField
	isOneofMessage := false

	if reflect.PtrTo(t).Implements(sizerType) {
		u.hassizer = true
	}
	if reflect.PtrTo(t).Implements(protosizerType) {
		u.hasprotosizer = true
	}
	// If the message can marshal itself, let it do it, for compatibility.
	// NOTE: This is not efficient.
	if reflect.PtrTo(t).Implements(marshalerType) {
		u.hasmarshaler = true
		atomic.StoreInt32(&u.initialized, 1)
		return
	}

	n := t.NumField()

	// deal with XXX fields first
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		if f.Tag.Get("protobuf_oneof") != "" {
			isOneofMessage = true
		}
		if !strings.HasPrefix(f.Name, "XXX_") {
			continue
		}
		switch f.Name {
		case "XXX_sizecache":
			u.sizecache = toField(&f)
		case "XXX_unrecognized":
			u.unrecognized = toField(&f)
		case "XXX_InternalExtensions":
			u.extensions = toField(&f)
			u.messageset = f.Tag.Get("protobuf_messageset") == "1"
		case "XXX_extensions":
			if f.Type.Kind() == reflect.Map {
				u.v1extensions = toField(&f)
			} else {
				u.bytesExtensions = toField(&f)
			}
		case "XXX_NoUnkeyedLiteral":
			// nothing to do
		default:
			panic("unknown XXX field: " + f.Name)
		}
		n--
	}

	// get oneof implementers
	var oneofImplementers []interface{}
	// gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler
	if isOneofMessage {
		switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
		case oneofFuncsIface:
			_, _, _, oneofImplementers = m.XXX_OneofFuncs()
		case oneofWrappersIface:
			oneofImplementers = m.XXX_OneofWrappers()
		}
	}

	// normal fields
	fields := make([]marshalFieldInfo, n) // batch allocation
	u.fields = make([]*marshalFieldInfo, 0, n)
	for i, j := 0, 0; i < t.NumField(); i++ {
		f := t.Field(i)

		if strings.HasPrefix(f.Name, "XXX_") {
			continue
		}
		field := &fields[j]
		j++
		field.name = f.Name
		u.fields = append(u.fields, field)
		if f.Tag.Get("protobuf_oneof") != "" {
			field.computeOneofFieldInfo(&f, oneofImplementers)
			continue
		}
		if f.Tag.Get("protobuf") == "" {
			// field has no tag (not in generated message), ignore it
			u.fields = u.fields[:len(u.fields)-1]
			j--
			continue
		}
		field.computeMarshalFieldInfo(&f)
	}

	// fields are marshaled in tag order on the wire.
	sort.Sort(byTag(u.fields))

	atomic.StoreInt32(&u.initialized, 1)
}

// helper for sorting fields by tag
type byTag []*marshalFieldInfo

func (a byTag) Len() int           { return len(a) }
func (a byTag) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag }

// getExtElemInfo returns the information to marshal an extension element.
// The info it returns is initialized.
func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
	// get from cache first
	u.RLock()
	e, ok := u.extElems[desc.Field]
	u.RUnlock()
	if ok {
		return e
	}

	t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct
	tags := strings.Split(desc.Tag, ",")
	tag, err := strconv.Atoi(tags[1])
	if err != nil {
		panic("tag is not an integer")
	}
	wt := wiretype(tags[0])
	sizr, marshalr := typeMarshaler(t, tags, false, false)
	e = &marshalElemInfo{
		wiretag:   uint64(tag)<<3 | wt,
		tagsize:   SizeVarint(uint64(tag) << 3),
		sizer:     sizr,
		marshaler: marshalr,
		isptr:     t.Kind() == reflect.Ptr,
	}

	// update cache
	u.Lock()
	if u.extElems == nil {
		u.extElems = make(map[int32]*marshalElemInfo)
	}
	u.extElems[desc.Field] = e
	u.Unlock()
	return e
}

// computeMarshalFieldInfo fills up the information to marshal a field.
func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
	// parse protobuf tag of the field.
	// tag has format of "bytes,49,opt,name=foo,def=hello!"
	tags := strings.Split(f.Tag.Get("protobuf"), ",")
	if tags[0] == "" {
		return
	}
	tag, err := strconv.Atoi(tags[1])
	if err != nil {
		panic("tag is not an integer")
	}
	wt := wiretype(tags[0])
	if tags[2] == "req" {
		fi.required = true
	}
	fi.setTag(f, tag, wt)
	fi.setMarshaler(f, tags)
}

func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
	fi.field = toField(f)
	fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
	fi.isPointer = true
	fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
	fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)

	ityp := f.Type // interface type
	for _, o := range oneofImplementers {
		t := reflect.TypeOf(o)
		if !t.Implements(ityp) {
			continue
		}
		sf := t.Elem().Field(0) // oneof implementer is a struct with a single field
		tags := strings.Split(sf.Tag.Get("protobuf"), ",")
		tag, err := strconv.Atoi(tags[1])
		if err != nil {
			panic("tag is not an integer")
		}
		wt := wiretype(tags[0])
		sizr, marshalr := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value
		fi.oneofElems[t.Elem()] = &marshalElemInfo{
			wiretag:   uint64(tag)<<3 | wt,
			tagsize:   SizeVarint(uint64(tag) << 3),
			sizer:     sizr,
			marshaler: marshalr,
		}
	}
}

// wiretype returns the wire encoding of the type.
func wiretype(encoding string) uint64 {
	switch encoding {
	case "fixed32":
		return WireFixed32
	case "fixed64":
		return WireFixed64
	case "varint", "zigzag32", "zigzag64":
		return WireVarint
	case "bytes":
		return WireBytes
	case "group":
		return WireStartGroup
	}
	panic("unknown wire type " + encoding)
}

// setTag fills up the tag (in wire format) and its size in the info of a field.
func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) {
	fi.field = toField(f)
	fi.wiretag = uint64(tag)<<3 | wt
	fi.tagsize = SizeVarint(uint64(tag) << 3)
}

// setMarshaler fills up the sizer and marshaler in the info of a field.
func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) {
	switch f.Type.Kind() {
	case reflect.Map:
		// map field
		fi.isPointer = true
		fi.sizer, fi.marshaler = makeMapMarshaler(f)
		return
	case reflect.Ptr, reflect.Slice:
		fi.isPointer = true
	}
	fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false)
}

// typeMarshaler returns the sizer and marshaler of a given field.
// t is the type of the field.
// tags is the generated "protobuf" tag of the field.
// If nozero is true, zero value is not marshaled to the wire.
// If oneof is true, it is a oneof field.
func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) {
	encoding := tags[0]

	pointer := false
	slice := false
	if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
		slice = true
		t = t.Elem()
	}
	if t.Kind() == reflect.Ptr {
		pointer = true
		t = t.Elem()
	}

	packed := false
	proto3 := false
	ctype := false
	isTime := false
	isDuration := false
	isWktPointer := false
	validateUTF8 := true
	for i := 2; i < len(tags); i++ {
		if tags[i] == "packed" {
			packed = true
		}
		if tags[i] == "proto3" {
			proto3 = true
		}
		if strings.HasPrefix(tags[i], "customtype=") {
			ctype = true
		}
		if tags[i] == "stdtime" {
			isTime = true
		}
		if tags[i] == "stdduration" {
			isDuration = true
		}
		if tags[i] == "wktptr" {
			isWktPointer = true
		}
	}
	validateUTF8 = validateUTF8 && proto3
	if !proto3 && !pointer && !slice {
		nozero = false
	}

	if ctype {
		if reflect.PtrTo(t).Implements(customType) {
			if slice {
				return makeMessageRefSliceMarshaler(getMarshalInfo(t))
			}
			if pointer {
				return makeCustomPtrMarshaler(getMarshalInfo(t))
			}
			return makeCustomMarshaler(getMarshalInfo(t))
		} else {
			panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t))
		}
	}

	if isTime {
		if pointer {
			if slice {
				return makeTimePtrSliceMarshaler(getMarshalInfo(t))
			}
			return makeTimePtrMarshaler(getMarshalInfo(t))
		}
		if slice {
			return makeTimeSliceMarshaler(getMarshalInfo(t))
		}
		return makeTimeMarshaler(getMarshalInfo(t))
	}

	if isDuration {
		if pointer {
			if slice {
				return makeDurationPtrSliceMarshaler(getMarshalInfo(t))
			}
			return makeDurationPtrMarshaler(getMarshalInfo(t))
		}
		if slice {
			return makeDurationSliceMarshaler(getMarshalInfo(t))
		}
		return makeDurationMarshaler(getMarshalInfo(t))
	}

	if isWktPointer {
		switch t.Kind() {
		case reflect.Float64:
			if pointer {
				if slice {
					return makeStdDoubleValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdDoubleValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdDoubleValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdDoubleValueMarshaler(getMarshalInfo(t))
		case reflect.Float32:
			if pointer {
				if slice {
					return makeStdFloatValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdFloatValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdFloatValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdFloatValueMarshaler(getMarshalInfo(t))
		case reflect.Int64:
			if pointer {
				if slice {
					return makeStdInt64ValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdInt64ValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdInt64ValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdInt64ValueMarshaler(getMarshalInfo(t))
		case reflect.Uint64:
			if pointer {
				if slice {
					return makeStdUInt64ValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdUInt64ValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdUInt64ValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdUInt64ValueMarshaler(getMarshalInfo(t))
		case reflect.Int32:
			if pointer {
				if slice {
					return makeStdInt32ValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdInt32ValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdInt32ValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdInt32ValueMarshaler(getMarshalInfo(t))
		case reflect.Uint32:
			if pointer {
				if slice {
					return makeStdUInt32ValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdUInt32ValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdUInt32ValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdUInt32ValueMarshaler(getMarshalInfo(t))
		case reflect.Bool:
			if pointer {
				if slice {
					return makeStdBoolValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdBoolValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdBoolValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdBoolValueMarshaler(getMarshalInfo(t))
		case reflect.String:
			if pointer {
				if slice {
					return makeStdStringValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdStringValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdStringValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdStringValueMarshaler(getMarshalInfo(t))
		case uint8SliceType:
			if pointer {
				if slice {
					return makeStdBytesValuePtrSliceMarshaler(getMarshalInfo(t))
				}
				return makeStdBytesValuePtrMarshaler(getMarshalInfo(t))
			}
			if slice {
				return makeStdBytesValueSliceMarshaler(getMarshalInfo(t))
			}
			return makeStdBytesValueMarshaler(getMarshalInfo(t))
		default:
			panic(fmt.Sprintf("unknown wktpointer type %#v", t))
		}
	}

	switch t.Kind() {
	case reflect.Bool:
		if pointer {
			return sizeBoolPtr, appendBoolPtr
		}
		if slice {
			if packed {
				return sizeBoolPackedSlice, appendBoolPackedSlice
			}
			return sizeBoolSlice, appendBoolSlice
		}
		if nozero {
			return sizeBoolValueNoZero, appendBoolValueNoZero
		}
		return sizeBoolValue, appendBoolValue
	case reflect.Uint32:
		switch encoding {
		case "fixed32":
			if pointer {
				return sizeFixed32Ptr, appendFixed32Ptr
			}
			if slice {
				if packed {
					return sizeFixed32PackedSlice, appendFixed32PackedSlice
				}
				return sizeFixed32Slice, appendFixed32Slice
			}
			if nozero {
				return sizeFixed32ValueNoZero, appendFixed32ValueNoZero
			}
			return sizeFixed32Value, appendFixed32Value
		case "varint":
			if pointer {
				return sizeVarint32Ptr, appendVarint32Ptr
			}
			if slice {
				if packed {
					return sizeVarint32PackedSlice, appendVarint32PackedSlice
				}
				return sizeVarint32Slice, appendVarint32Slice
			}
			if nozero {
				return sizeVarint32ValueNoZero, appendVarint32ValueNoZero
			}
			return sizeVarint32Value, appendVarint32Value
		}
	case reflect.Int32:
		switch encoding {
		case "fixed32":
			if pointer {
				return sizeFixedS32Ptr, appendFixedS32Ptr
			}
			if slice {
				if packed {
					return sizeFixedS32PackedSlice, appendFixedS32PackedSlice
				}
				return sizeFixedS32Slice, appendFixedS32Slice
			}
			if nozero {
				return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero
			}
			return sizeFixedS32Value, appendFixedS32Value
		case "varint":
			if pointer {
				return sizeVarintS32Ptr, appendVarintS32Ptr
			}
			if slice {
				if packed {
					return sizeVarintS32PackedSlice, appendVarintS32PackedSlice
				}
				return sizeVarintS32Slice, appendVarintS32Slice
			}
			if nozero {
				return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero
			}
			return sizeVarintS32Value, appendVarintS32Value
		case "zigzag32":
			if pointer {
				return sizeZigzag32Ptr, appendZigzag32Ptr
			}
			if slice {
				if packed {
					return sizeZigzag32PackedSlice, appendZigzag32PackedSlice
				}
				return sizeZigzag32Slice, appendZigzag32Slice
			}
			if nozero {
				return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero
			}
			return sizeZigzag32Value, appendZigzag32Value
		}
	case reflect.Uint64:
		switch encoding {
		case "fixed64":
			if pointer {
				return sizeFixed64Ptr, appendFixed64Ptr
			}
			if slice {
				if packed {
					return sizeFixed64PackedSlice, appendFixed64PackedSlice
				}
				return sizeFixed64Slice, appendFixed64Slice
			}
			if nozero {
				return sizeFixed64ValueNoZero, appendFixed64ValueNoZero
			}
			return sizeFixed64Value, appendFixed64Value
		case "varint":
			if pointer {
				return sizeVarint64Ptr, appendVarint64Ptr
			}
			if slice {
				if packed {
					return sizeVarint64PackedSlice, appendVarint64PackedSlice
				}
				return sizeVarint64Slice, appendVarint64Slice
			}
			if nozero {
				return sizeVarint64ValueNoZero, appendVarint64ValueNoZero
			}
			return sizeVarint64Value, appendVarint64Value
		}
	case reflect.Int64:
		switch encoding {
		case "fixed64":
			if pointer {
				return sizeFixedS64Ptr, appendFixedS64Ptr
			}
			if slice {
				if packed {
					return sizeFixedS64PackedSlice, appendFixedS64PackedSlice
				}
				return sizeFixedS64Slice, appendFixedS64Slice
			}
			if nozero {
				return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero
			}
			return sizeFixedS64Value, appendFixedS64Value
		case "varint":
			if pointer {
				return sizeVarintS64Ptr, appendVarintS64Ptr
			}
			if slice {
				if packed {
					return sizeVarintS64PackedSlice, appendVarintS64PackedSlice
				}
				return sizeVarintS64Slice, appendVarintS64Slice
			}
			if nozero {
				return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero
			}
			return sizeVarintS64Value, appendVarintS64Value
		case "zigzag64":
			if pointer {
				return sizeZigzag64Ptr, appendZigzag64Ptr
			}
			if slice {
				if packed {
					return sizeZigzag64PackedSlice, appendZigzag64PackedSlice
				}
				return sizeZigzag64Slice, appendZigzag64Slice
			}
			if nozero {
				return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero
			}
			return sizeZigzag64Value, appendZigzag64Value
		}
	case reflect.Float32:
		if pointer {
			return sizeFloat32Ptr, appendFloat32Ptr
		}
		if slice {
			if packed {
				return sizeFloat32PackedSlice, appendFloat32PackedSlice
			}
			return sizeFloat32Slice, appendFloat32Slice
		}
		if nozero {
			return sizeFloat32ValueNoZero, appendFloat32ValueNoZero
		}
		return sizeFloat32Value, appendFloat32Value
	case reflect.Float64:
		if pointer {
			return sizeFloat64Ptr, appendFloat64Ptr
		}
		if slice {
			if packed {
				return sizeFloat64PackedSlice, appendFloat64PackedSlice
			}
			return sizeFloat64Slice, appendFloat64Slice
		}
		if nozero {
			return sizeFloat64ValueNoZero, appendFloat64ValueNoZero
		}
		return sizeFloat64Value, appendFloat64Value
	case reflect.String:
		if validateUTF8 {
			if pointer {
				return sizeStringPtr, appendUTF8StringPtr
			}
			if slice {
				return sizeStringSlice, appendUTF8StringSlice
			}
			if nozero {
				return sizeStringValueNoZero, appendUTF8StringValueNoZero
			}
			return sizeStringValue, appendUTF8StringValue
		}
		if pointer {
			return sizeStringPtr, appendStringPtr
		}
		if slice {
			return sizeStringSlice, appendStringSlice
		}
		if nozero {
			return sizeStringValueNoZero, appendStringValueNoZero
		}
		return sizeStringValue, appendStringValue
	case reflect.Slice:
		if slice {
			return sizeBytesSlice, appendBytesSlice
		}
		if oneof {
			// Oneof bytes field may also have "proto3" tag.
			// We want to marshal it as a oneof field. Do this
			// check before the proto3 check.
			return sizeBytesOneof, appendBytesOneof
		}
		if proto3 {
			return sizeBytes3, appendBytes3
		}
		return sizeBytes, appendBytes
	case reflect.Struct:
		switch encoding {
		case "group":
			if slice {
				return makeGroupSliceMarshaler(getMarshalInfo(t))
			}
			return makeGroupMarshaler(getMarshalInfo(t))
		case "bytes":
			if pointer {
				if slice {
					return makeMessageSliceMarshaler(getMarshalInfo(t))
				}
				return makeMessageMarshaler(getMarshalInfo(t))
			} else {
				if slice {
					return makeMessageRefSliceMarshaler(getMarshalInfo(t))
				}
				return makeMessageRefMarshaler(getMarshalInfo(t))
			}
		}
	}
	panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding))
}

// Below are functions to size/marshal a specific type of a field.
// They are stored in the field's info, and called by function pointers.
// They have type sizer or marshaler.

func sizeFixed32Value(_ pointer, tagsize int) int {
	return 4 + tagsize
}
func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toUint32()
	if v == 0 {
		return 0
	}
	return 4 + tagsize
}
func sizeFixed32Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toUint32Ptr()
	if p == nil {
		return 0
	}
	return 4 + tagsize
}
func sizeFixed32Slice(ptr pointer, tagsize int) int {
	s := *ptr.toUint32Slice()
	return (4 + tagsize) * len(s)
}
func sizeFixed32PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toUint32Slice()
	if len(s) == 0 {
		return 0
	}
	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
}
func sizeFixedS32Value(_ pointer, tagsize int) int {
	return 4 + tagsize
}
func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toInt32()
	if v == 0 {
		return 0
	}
	return 4 + tagsize
}
func sizeFixedS32Ptr(ptr pointer, tagsize int) int {
	p := ptr.getInt32Ptr()
	if p == nil {
		return 0
	}
	return 4 + tagsize
}
func sizeFixedS32Slice(ptr pointer, tagsize int) int {
	s := ptr.getInt32Slice()
	return (4 + tagsize) * len(s)
}
func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int {
	s := ptr.getInt32Slice()
	if len(s) == 0 {
		return 0
	}
	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
}
func sizeFloat32Value(_ pointer, tagsize int) int {
	return 4 + tagsize
}
func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int {
	v := math.Float32bits(*ptr.toFloat32())
	if v == 0 {
		return 0
	}
	return 4 + tagsize
}
func sizeFloat32Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toFloat32Ptr()
	if p == nil {
		return 0
	}
	return 4 + tagsize
}
func sizeFloat32Slice(ptr pointer, tagsize int) int {
	s := *ptr.toFloat32Slice()
	return (4 + tagsize) * len(s)
}
func sizeFloat32PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toFloat32Slice()
	if len(s) == 0 {
		return 0
	}
	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
}
func sizeFixed64Value(_ pointer, tagsize int) int {
	return 8 + tagsize
}
func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toUint64()
	if v == 0 {
		return 0
	}
	return 8 + tagsize
}
func sizeFixed64Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toUint64Ptr()
	if p == nil {
		return 0
	}
	return 8 + tagsize
}
func sizeFixed64Slice(ptr pointer, tagsize int) int {
	s := *ptr.toUint64Slice()
	return (8 + tagsize) * len(s)
}
func sizeFixed64PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toUint64Slice()
	if len(s) == 0 {
		return 0
	}
	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
}
func sizeFixedS64Value(_ pointer, tagsize int) int {
	return 8 + tagsize
}
func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toInt64()
	if v == 0 {
		return 0
	}
	return 8 + tagsize
}
func sizeFixedS64Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toInt64Ptr()
	if p == nil {
		return 0
	}
	return 8 + tagsize
}
func sizeFixedS64Slice(ptr pointer, tagsize int) int {
	s := *ptr.toInt64Slice()
	return (8 + tagsize) * len(s)
}
func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toInt64Slice()
	if len(s) == 0 {
		return 0
	}
	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
}
func sizeFloat64Value(_ pointer, tagsize int) int {
	return 8 + tagsize
}
func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int {
	v := math.Float64bits(*ptr.toFloat64())
	if v == 0 {
		return 0
	}
	return 8 + tagsize
}
func sizeFloat64Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toFloat64Ptr()
	if p == nil {
		return 0
	}
	return 8 + tagsize
}
func sizeFloat64Slice(ptr pointer, tagsize int) int {
	s := *ptr.toFloat64Slice()
	return (8 + tagsize) * len(s)
}
func sizeFloat64PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toFloat64Slice()
	if len(s) == 0 {
		return 0
	}
	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
}
func sizeVarint32Value(ptr pointer, tagsize int) int {
	v := *ptr.toUint32()
	return SizeVarint(uint64(v)) + tagsize
}
func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toUint32()
	if v == 0 {
		return 0
	}
	return SizeVarint(uint64(v)) + tagsize
}
func sizeVarint32Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toUint32Ptr()
	if p == nil {
		return 0
	}
	return SizeVarint(uint64(*p)) + tagsize
}
func sizeVarint32Slice(ptr pointer, tagsize int) int {
	s := *ptr.toUint32Slice()
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v)) + tagsize
	}
	return n
}
func sizeVarint32PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toUint32Slice()
	if len(s) == 0 {
		return 0
	}
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v))
	}
	return n + SizeVarint(uint64(n)) + tagsize
}
func sizeVarintS32Value(ptr pointer, tagsize int) int {
	v := *ptr.toInt32()
	return SizeVarint(uint64(v)) + tagsize
}
func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toInt32()
	if v == 0 {
		return 0
	}
	return SizeVarint(uint64(v)) + tagsize
}
func sizeVarintS32Ptr(ptr pointer, tagsize int) int {
	p := ptr.getInt32Ptr()
	if p == nil {
		return 0
	}
	return SizeVarint(uint64(*p)) + tagsize
}
func sizeVarintS32Slice(ptr pointer, tagsize int) int {
	s := ptr.getInt32Slice()
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v)) + tagsize
	}
	return n
}
func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int {
	s := ptr.getInt32Slice()
	if len(s) == 0 {
		return 0
	}
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v))
	}
	return n + SizeVarint(uint64(n)) + tagsize
}
func sizeVarint64Value(ptr pointer, tagsize int) int {
	v := *ptr.toUint64()
	return SizeVarint(v) + tagsize
}
func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toUint64()
	if v == 0 {
		return 0
	}
	return SizeVarint(v) + tagsize
}
func sizeVarint64Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toUint64Ptr()
	if p == nil {
		return 0
	}
	return SizeVarint(*p) + tagsize
}
func sizeVarint64Slice(ptr pointer, tagsize int) int {
	s := *ptr.toUint64Slice()
	n := 0
	for _, v := range s {
		n += SizeVarint(v) + tagsize
	}
	return n
}
func sizeVarint64PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toUint64Slice()
	if len(s) == 0 {
		return 0
	}
	n := 0
	for _, v := range s {
		n += SizeVarint(v)
	}
	return n + SizeVarint(uint64(n)) + tagsize
}
func sizeVarintS64Value(ptr pointer, tagsize int) int {
	v := *ptr.toInt64()
	return SizeVarint(uint64(v)) + tagsize
}
func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toInt64()
	if v == 0 {
		return 0
	}
	return SizeVarint(uint64(v)) + tagsize
}
func sizeVarintS64Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toInt64Ptr()
	if p == nil {
		return 0
	}
	return SizeVarint(uint64(*p)) + tagsize
}
func sizeVarintS64Slice(ptr pointer, tagsize int) int {
	s := *ptr.toInt64Slice()
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v)) + tagsize
	}
	return n
}
func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toInt64Slice()
	if len(s) == 0 {
		return 0
	}
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v))
	}
	return n + SizeVarint(uint64(n)) + tagsize
}
func sizeZigzag32Value(ptr pointer, tagsize int) int {
	v := *ptr.toInt32()
	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
}
func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toInt32()
	if v == 0 {
		return 0
	}
	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
}
func sizeZigzag32Ptr(ptr pointer, tagsize int) int {
	p := ptr.getInt32Ptr()
	if p == nil {
		return 0
	}
	v := *p
	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
}
func sizeZigzag32Slice(ptr pointer, tagsize int) int {
	s := ptr.getInt32Slice()
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
	}
	return n
}
func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int {
	s := ptr.getInt32Slice()
	if len(s) == 0 {
		return 0
	}
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
	}
	return n + SizeVarint(uint64(n)) + tagsize
}
func sizeZigzag64Value(ptr pointer, tagsize int) int {
	v := *ptr.toInt64()
	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
}
func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toInt64()
	if v == 0 {
		return 0
	}
	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
}
func sizeZigzag64Ptr(ptr pointer, tagsize int) int {
	p := *ptr.toInt64Ptr()
	if p == nil {
		return 0
	}
	v := *p
	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
}
func sizeZigzag64Slice(ptr pointer, tagsize int) int {
	s := *ptr.toInt64Slice()
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
	}
	return n
}
func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toInt64Slice()
	if len(s) == 0 {
		return 0
	}
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
	}
	return n + SizeVarint(uint64(n)) + tagsize
}
func sizeBoolValue(_ pointer, tagsize int) int {
	return 1 + tagsize
}
func sizeBoolValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toBool()
	if !v {
		return 0
	}
	return 1 + tagsize
}
func sizeBoolPtr(ptr pointer, tagsize int) int {
	p := *ptr.toBoolPtr()
	if p == nil {
		return 0
	}
	return 1 + tagsize
}
func sizeBoolSlice(ptr pointer, tagsize int) int {
	s := *ptr.toBoolSlice()
	return (1 + tagsize) * len(s)
}
func sizeBoolPackedSlice(ptr pointer, tagsize int) int {
	s := *ptr.toBoolSlice()
	if len(s) == 0 {
		return 0
	}
	return len(s) + SizeVarint(uint64(len(s))) + tagsize
}
func sizeStringValue(ptr pointer, tagsize int) int {
	v := *ptr.toString()
	return len(v) + SizeVarint(uint64(len(v))) + tagsize
}
func sizeStringValueNoZero(ptr pointer, tagsize int) int {
	v := *ptr.toString()
	if v == "" {
		return 0
	}
	return len(v) + SizeVarint(uint64(len(v))) + tagsize
}
func sizeStringPtr(ptr pointer, tagsize int) int {
	p := *ptr.toStringPtr()
	if p == nil {
		return 0
	}
	v := *p
	return len(v) + SizeVarint(uint64(len(v))) + tagsize
}
func sizeStringSlice(ptr pointer, tagsize int) int {
	s := *ptr.toStringSlice()
	n := 0
	for _, v := range s {
		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
	}
	return n
}
func sizeBytes(ptr pointer, tagsize int) int {
	v := *ptr.toBytes()
	if v == nil {
		return 0
	}
	return len(v) + SizeVarint(uint64(len(v))) + tagsize
}
func sizeBytes3(ptr pointer, tagsize int) int {
	v := *ptr.toBytes()
	if len(v) == 0 {
		return 0
	}
	return len(v) + SizeVarint(uint64(len(v))) + tagsize
}
func sizeBytesOneof(ptr pointer, tagsize int) int {
	v := *ptr.toBytes()
	return len(v) + SizeVarint(uint64(len(v))) + tagsize
}
func sizeBytesSlice(ptr pointer, tagsize int) int {
	s := *ptr.toBytesSlice()
	n := 0
	for _, v := range s {
		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
	}
	return n
}

// appendFixed32 appends an encoded fixed32 to b.
func appendFixed32(b []byte, v uint32) []byte {
	b = append(b,
		byte(v),
		byte(v>>8),
		byte(v>>16),
		byte(v>>24))
	return b
}

// appendFixed64 appends an encoded fixed64 to b.
func appendFixed64(b []byte, v uint64) []byte {
	b = append(b,
		byte(v),
		byte(v>>8),
		byte(v>>16),
		byte(v>>24),
		byte(v>>32),
		byte(v>>40),
		byte(v>>48),
		byte(v>>56))
	return b
}

// appendVarint appends an encoded varint to b.
func appendVarint(b []byte, v uint64) []byte {
	// TODO: make 1-byte (maybe 2-byte) case inline-able, once we
	// have non-leaf inliner.
	switch {
	case v < 1<<7:
		b = append(b, byte(v))
	case v < 1<<14:
		b = append(b,
			byte(v&0x7f|0x80),
			byte(v>>7))
	case v < 1<<21:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte(v>>14))
	case v < 1<<28:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte((v>>14)&0x7f|0x80),
			byte(v>>21))
	case v < 1<<35:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte((v>>14)&0x7f|0x80),
			byte((v>>21)&0x7f|0x80),
			byte(v>>28))
	case v < 1<<42:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte((v>>14)&0x7f|0x80),
			byte((v>>21)&0x7f|0x80),
			byte((v>>28)&0x7f|0x80),
			byte(v>>35))
	case v < 1<<49:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte((v>>14)&0x7f|0x80),
			byte((v>>21)&0x7f|0x80),
			byte((v>>28)&0x7f|0x80),
			byte((v>>35)&0x7f|0x80),
			byte(v>>42))
	case v < 1<<56:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte((v>>14)&0x7f|0x80),
			byte((v>>21)&0x7f|0x80),
			byte((v>>28)&0x7f|0x80),
			byte((v>>35)&0x7f|0x80),
			byte((v>>42)&0x7f|0x80),
			byte(v>>49))
	case v < 1<<63:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte((v>>14)&0x7f|0x80),
			byte((v>>21)&0x7f|0x80),
			byte((v>>28)&0x7f|0x80),
			byte((v>>35)&0x7f|0x80),
			byte((v>>42)&0x7f|0x80),
			byte((v>>49)&0x7f|0x80),
			byte(v>>56))
	default:
		b = append(b,
			byte(v&0x7f|0x80),
			byte((v>>7)&0x7f|0x80),
			byte((v>>14)&0x7f|0x80),
			byte((v>>21)&0x7f|0x80),
			byte((v>>28)&0x7f|0x80),
			byte((v>>35)&0x7f|0x80),
			byte((v>>42)&0x7f|0x80),
			byte((v>>49)&0x7f|0x80),
			byte((v>>56)&0x7f|0x80),
			1)
	}
	return b
}

func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint32()
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, v)
	return b, nil
}
func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint32()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, v)
	return b, nil
}
func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toUint32Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, *p)
	return b, nil
}
func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint32Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendFixed32(b, v)
	}
	return b, nil
}
func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint32Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	b = appendVarint(b, uint64(4*len(s)))
	for _, v := range s {
		b = appendFixed32(b, v)
	}
	return b, nil
}
func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt32()
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, uint32(v))
	return b, nil
}
func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt32()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, uint32(v))
	return b, nil
}
func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := ptr.getInt32Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, uint32(*p))
	return b, nil
}
func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := ptr.getInt32Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendFixed32(b, uint32(v))
	}
	return b, nil
}
func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := ptr.getInt32Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	b = appendVarint(b, uint64(4*len(s)))
	for _, v := range s {
		b = appendFixed32(b, uint32(v))
	}
	return b, nil
}
func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := math.Float32bits(*ptr.toFloat32())
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, v)
	return b, nil
}
func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := math.Float32bits(*ptr.toFloat32())
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, v)
	return b, nil
}
func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toFloat32Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed32(b, math.Float32bits(*p))
	return b, nil
}
func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toFloat32Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendFixed32(b, math.Float32bits(v))
	}
	return b, nil
}
func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toFloat32Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	b = appendVarint(b, uint64(4*len(s)))
	for _, v := range s {
		b = appendFixed32(b, math.Float32bits(v))
	}
	return b, nil
}
func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint64()
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, v)
	return b, nil
}
func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint64()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, v)
	return b, nil
}
func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toUint64Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, *p)
	return b, nil
}
func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint64Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendFixed64(b, v)
	}
	return b, nil
}
func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint64Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	b = appendVarint(b, uint64(8*len(s)))
	for _, v := range s {
		b = appendFixed64(b, v)
	}
	return b, nil
}
func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt64()
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, uint64(v))
	return b, nil
}
func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt64()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, uint64(v))
	return b, nil
}
func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toInt64Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, uint64(*p))
	return b, nil
}
func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toInt64Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendFixed64(b, uint64(v))
	}
	return b, nil
}
func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toInt64Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	b = appendVarint(b, uint64(8*len(s)))
	for _, v := range s {
		b = appendFixed64(b, uint64(v))
	}
	return b, nil
}
func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := math.Float64bits(*ptr.toFloat64())
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, v)
	return b, nil
}
func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := math.Float64bits(*ptr.toFloat64())
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, v)
	return b, nil
}
func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toFloat64Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendFixed64(b, math.Float64bits(*p))
	return b, nil
}
func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toFloat64Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendFixed64(b, math.Float64bits(v))
	}
	return b, nil
}
func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toFloat64Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	b = appendVarint(b, uint64(8*len(s)))
	for _, v := range s {
		b = appendFixed64(b, math.Float64bits(v))
	}
	return b, nil
}
func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint32()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v))
	return b, nil
}
func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint32()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v))
	return b, nil
}
func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toUint32Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(*p))
	return b, nil
}
func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint32Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64(v))
	}
	return b, nil
}
func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint32Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	// compute size
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v))
	}
	b = appendVarint(b, uint64(n))
	for _, v := range s {
		b = appendVarint(b, uint64(v))
	}
	return b, nil
}
func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt32()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v))
	return b, nil
}
func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt32()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v))
	return b, nil
}
func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := ptr.getInt32Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(*p))
	return b, nil
}
func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := ptr.getInt32Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64(v))
	}
	return b, nil
}
func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := ptr.getInt32Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	// compute size
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v))
	}
	b = appendVarint(b, uint64(n))
	for _, v := range s {
		b = appendVarint(b, uint64(v))
	}
	return b, nil
}
func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint64()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, v)
	return b, nil
}
func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toUint64()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, v)
	return b, nil
}
func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toUint64Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, *p)
	return b, nil
}
func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint64Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, v)
	}
	return b, nil
}
func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toUint64Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	// compute size
	n := 0
	for _, v := range s {
		n += SizeVarint(v)
	}
	b = appendVarint(b, uint64(n))
	for _, v := range s {
		b = appendVarint(b, v)
	}
	return b, nil
}
func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt64()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v))
	return b, nil
}
func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt64()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v))
	return b, nil
}
func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toInt64Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(*p))
	return b, nil
}
func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toInt64Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64(v))
	}
	return b, nil
}
func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toInt64Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	// compute size
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v))
	}
	b = appendVarint(b, uint64(n))
	for _, v := range s {
		b = appendVarint(b, uint64(v))
	}
	return b, nil
}
func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt32()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
	return b, nil
}
func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt32()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
	return b, nil
}
func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := ptr.getInt32Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	v := *p
	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
	return b, nil
}
func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := ptr.getInt32Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
	}
	return b, nil
}
func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := ptr.getInt32Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	// compute size
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
	}
	b = appendVarint(b, uint64(n))
	for _, v := range s {
		b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
	}
	return b, nil
}
func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt64()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
	return b, nil
}
func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toInt64()
	if v == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
	return b, nil
}
func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toInt64Ptr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	v := *p
	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
	return b, nil
}
func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toInt64Slice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
	}
	return b, nil
}
func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toInt64Slice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	// compute size
	n := 0
	for _, v := range s {
		n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
	}
	b = appendVarint(b, uint64(n))
	for _, v := range s {
		b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
	}
	return b, nil
}
func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toBool()
	b = appendVarint(b, wiretag)
	if v {
		b = append(b, 1)
	} else {
		b = append(b, 0)
	}
	return b, nil
}
func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toBool()
	if !v {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = append(b, 1)
	return b, nil
}

func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toBoolPtr()
	if p == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	if *p {
		b = append(b, 1)
	} else {
		b = append(b, 0)
	}
	return b, nil
}
func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toBoolSlice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		if v {
			b = append(b, 1)
		} else {
			b = append(b, 0)
		}
	}
	return b, nil
}
func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toBoolSlice()
	if len(s) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag&^7|WireBytes)
	b = appendVarint(b, uint64(len(s)))
	for _, v := range s {
		if v {
			b = append(b, 1)
		} else {
			b = append(b, 0)
		}
	}
	return b, nil
}
func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toString()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	return b, nil
}
func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toString()
	if v == "" {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	return b, nil
}
func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	p := *ptr.toStringPtr()
	if p == nil {
		return b, nil
	}
	v := *p
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	return b, nil
}
func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toStringSlice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64(len(v)))
		b = append(b, v...)
	}
	return b, nil
}
func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	var invalidUTF8 bool
	v := *ptr.toString()
	if !utf8.ValidString(v) {
		invalidUTF8 = true
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	if invalidUTF8 {
		return b, errInvalidUTF8
	}
	return b, nil
}
func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	var invalidUTF8 bool
	v := *ptr.toString()
	if v == "" {
		return b, nil
	}
	if !utf8.ValidString(v) {
		invalidUTF8 = true
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	if invalidUTF8 {
		return b, errInvalidUTF8
	}
	return b, nil
}
func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	var invalidUTF8 bool
	p := *ptr.toStringPtr()
	if p == nil {
		return b, nil
	}
	v := *p
	if !utf8.ValidString(v) {
		invalidUTF8 = true
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	if invalidUTF8 {
		return b, errInvalidUTF8
	}
	return b, nil
}
func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	var invalidUTF8 bool
	s := *ptr.toStringSlice()
	for _, v := range s {
		if !utf8.ValidString(v) {
			invalidUTF8 = true
		}
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64(len(v)))
		b = append(b, v...)
	}
	if invalidUTF8 {
		return b, errInvalidUTF8
	}
	return b, nil
}
func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toBytes()
	if v == nil {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	return b, nil
}
func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toBytes()
	if len(v) == 0 {
		return b, nil
	}
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	return b, nil
}
func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	v := *ptr.toBytes()
	b = appendVarint(b, wiretag)
	b = appendVarint(b, uint64(len(v)))
	b = append(b, v...)
	return b, nil
}
func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
	s := *ptr.toBytesSlice()
	for _, v := range s {
		b = appendVarint(b, wiretag)
		b = appendVarint(b, uint64(len(v)))
		b = append(b, v...)
	}
	return b, nil
}

// makeGroupMarshaler returns the sizer and marshaler for a group.
// u is the marshal info of the underlying message.
func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) {
	return func(ptr pointer, tagsize int) int {
			p := ptr.getPointer()
			if p.isNil() {
				return 0
			}
			return u.size(p) + 2*tagsize
		},
		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
			p := ptr.getPointer()
			if p.isNil() {
				return b, nil
			}
			var err error
			b = appendVarint(b, wiretag) // start group
			b, err = u.marshal(b, p, deterministic)
			b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
			return b, err
		}
}

// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice.
// u is the marshal info of the underlying message.
func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
	return func(ptr pointer, tagsize int) int {
			s := ptr.getPointerSlice()
			n := 0
			for _, v := range s {
				if v.isNil() {
					continue
				}
				n += u.size(v) + 2*tagsize
			}
			return n
		},
		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
			s := ptr.getPointerSlice()
			var err error
			var nerr nonFatal
			for _, v := range s {
				if v.isNil() {
					return b, errRepeatedHasNil
				}
				b = appendVarint(b, wiretag) // start group
				b, err = u.marshal(b, v, deterministic)
				b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
				if !nerr.Merge(err) {
					if err == ErrNil {
						err = errRepeatedHasNil
					}
					return b, err
				}
			}
			return b, nerr.E
		}
}

// makeMessageMarshaler returns the sizer and marshaler for a message field.
// u is the marshal info of the message.
func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) {
	return func(ptr pointer, tagsize int) int {
			p := ptr.getPointer()
			if p.isNil() {
				return 0
			}
			siz := u.size(p)
			return siz + SizeVarint(uint64(siz)) + tagsize
		},
		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
			p := ptr.getPointer()
			if p.isNil() {
				return b, nil
			}
			b = appendVarint(b, wiretag)
			siz := u.cachedsize(p)
			b = appendVarint(b, uint64(siz))
			return u.marshal(b, p, deterministic)
		}
}

// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice.
// u is the marshal info of the message.
func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
	return func(ptr pointer, tagsize int) int {
			s := ptr.getPointerSlice()
			n := 0
			for _, v := range s {
				if v.isNil() {
					continue
				}
				siz := u.size(v)
				n += siz + SizeVarint(uint64(siz)) + tagsize
			}
			return n
		},
		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
			s := ptr.getPointerSlice()
			var err error
			var nerr nonFatal
			for _, v := range s {
				if v.isNil() {
					return b, errRepeatedHasNil
				}
				b = appendVarint(b, wiretag)
				siz := u.cachedsize(v)
				b = appendVarint(b, uint64(siz))
				b, err = u.marshal(b, v, deterministic)

				if !nerr.Merge(err) {
					if err == ErrNil {
						err = errRepeatedHasNil
					}
					return b, err
				}
			}
			return b, nerr.E
		}
}

// makeMapMarshaler returns the sizer and marshaler for a map field.
// f is the pointer to the reflect data structure of the field.
func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
	// figure out key and value type
	t := f.Type
	keyType := t.Key()
	valType := t.Elem()
	tags := strings.Split(f.Tag.Get("protobuf"), ",")
	keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",")
	valTags := strings.Split(f.Tag.Get("protobuf_val"), ",")
	stdOptions := false
	for _, t := range tags {
		if strings.HasPrefix(t, "customtype=") {
			valTags = append(valTags, t)
		}
		if t == "stdtime" {
			valTags = append(valTags, t)
			stdOptions = true
		}
		if t == "stdduration" {
			valTags = append(valTags, t)
			stdOptions = true
		}
		if t == "wktptr" {
			valTags = append(valTags, t)
		}
	}
	keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map
	valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map
	keyWireTag := 1<<3 | wiretype(keyTags[0])
	valWireTag := 2<<3 | wiretype(valTags[0])

	// We create an interface to get the addresses of the map key and value.
	// If value is pointer-typed, the interface is a direct interface, the
	// idata itself is the value. Otherwise, the idata is the pointer to the
	// value.
	// Key cannot be pointer-typed.
	valIsPtr := valType.Kind() == reflect.Ptr

	// If value is a message with nested maps, calling
	// valSizer in marshal may be quadratic. We should use
	// cached version in marshal (but not in size).
	// If value is not message type, we don't have size cache,
	// but it cannot be nested either. Just use valSizer.
	valCachedSizer := valSizer
	if valIsPtr && !stdOptions && valType.Elem().Kind() == reflect.Struct {
		u := getMarshalInfo(valType.Elem())
		valCachedSizer = func(ptr pointer, tagsize int) int {
			// Same as message sizer, but use cache.
			p := ptr.getPointer()
			if p.isNil() {
				return 0
			}
			siz := u.cachedsize(p)
			return siz + SizeVarint(uint64(siz)) + tagsize
		}
	}
	return func(ptr pointer, tagsize int) int {
			m := ptr.asPointerTo(t).Elem() // the map
			n := 0
			for _, k := range m.MapKeys() {
				ki := k.Interface()
				vi := m.MapIndex(k).Interface()
				kaddr := toAddrPointer(&ki, false)             // pointer to key
				vaddr := toAddrPointer(&vi, valIsPtr)          // pointer to value
				siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
				n += siz + SizeVarint(uint64(siz)) + tagsize
			}
			return n
		},
		func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) {
			m := ptr.asPointerTo(t).Elem() // the map
			var err error
			keys := m.MapKeys()
			if len(keys) > 1 && deterministic {
				sort.Sort(mapKeys(keys))
			}

			var nerr nonFatal
			for _, k := range keys {
				ki := k.Interface()
				vi := m.MapIndex(k).Interface()
				kaddr := toAddrPointer(&ki, false)    // pointer to key
				vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
				b = appendVarint(b, tag)
				siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
				b = appendVarint(b, uint64(siz))
				b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)
				if !nerr.Merge(err) {
					return b, err
				}
				b, err = valMarshaler(b, vaddr, valWireTag, deterministic)
				if err != ErrNil && !nerr.Merge(err) { // allow nil value in map
					return b, err
				}
			}
			return b, nerr.E
		}
}

// makeOneOfMarshaler returns the sizer and marshaler for a oneof field.
// fi is the marshal info of the field.
// f is the pointer to the reflect data structure of the field.
func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) {
	// Oneof field is an interface. We need to get the actual data type on the fly.
	t := f.Type
	return func(ptr pointer, _ int) int {
			p := ptr.getInterfacePointer()
			if p.isNil() {
				return 0
			}
			v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
			telem := v.Type()
			e := fi.oneofElems[telem]
			return e.sizer(p, e.tagsize)
		},
		func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) {
			p := ptr.getInterfacePointer()
			if p.isNil() {
				return b, nil
			}
			v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
			telem := v.Type()
			if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() {
				return b, errOneofHasNil
			}
			e := fi.oneofElems[telem]
			return e.marshaler(b, p, e.wiretag, deterministic)
		}
}

// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field.
func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {
	m, mu := ext.extensionsRead()
	if m == nil {
		return 0
	}
	mu.Lock()

	n := 0
	for _, e := range m {
		if e.value == nil || e.desc == nil {
			// Extension is only in its encoded form.
			n += len(e.enc)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.
		ei := u.getExtElemInfo(e.desc)
		v := e.value
		p := toAddrPointer(&v, ei.isptr)
		n += ei.sizer(p, ei.tagsize)
	}
	mu.Unlock()
	return n
}

// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b.
func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
	m, mu := ext.extensionsRead()
	if m == nil {
		return b, nil
	}
	mu.Lock()
	defer mu.Unlock()

	var err error
	var nerr nonFatal

	// Fast-path for common cases: zero or one extensions.
	// Don't bother sorting the keys.
	if len(m) <= 1 {
		for _, e := range m {
			if e.value == nil || e.desc == nil {
				// Extension is only in its encoded form.
				b = append(b, e.enc...)
				continue
			}

			// We don't skip extensions that have an encoded form set,
			// because the extension value may have been mutated after
			// the last time this function was called.

			ei := u.getExtElemInfo(e.desc)
			v := e.value
			p := toAddrPointer(&v, ei.isptr)
			b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
			if !nerr.Merge(err) {
				return b, err
			}
		}
		return b, nerr.E
	}

	// Sort the keys to provide a deterministic encoding.
	// Not sure this is required, but the old code does it.
	keys := make([]int, 0, len(m))
	for k := range m {
		keys = append(keys, int(k))
	}
	sort.Ints(keys)

	for _, k := range keys {
		e := m[int32(k)]
		if e.value == nil || e.desc == nil {
			// Extension is only in its encoded form.
			b = append(b, e.enc...)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		ei := u.getExtElemInfo(e.desc)
		v := e.value
		p := toAddrPointer(&v, ei.isptr)
		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
		if !nerr.Merge(err) {
			return b, err
		}
	}
	return b, nerr.E
}

// message set format is:
//   message MessageSet {
//     repeated group Item = 1 {
//       required int32 type_id = 2;
//       required string message = 3;
//     };
//   }

// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field
// in message set format (above).
func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {
	m, mu := ext.extensionsRead()
	if m == nil {
		return 0
	}
	mu.Lock()

	n := 0
	for id, e := range m {
		n += 2                          // start group, end group. tag = 1 (size=1)
		n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1)

		if e.value == nil || e.desc == nil {
			// Extension is only in its encoded form.
			msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
			siz := len(msgWithLen)
			n += siz + 1 // message, tag = 3 (size=1)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		ei := u.getExtElemInfo(e.desc)
		v := e.value
		p := toAddrPointer(&v, ei.isptr)
		n += ei.sizer(p, 1) // message, tag = 3 (size=1)
	}
	mu.Unlock()
	return n
}

// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above)
// to the end of byte slice b.
func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
	m, mu := ext.extensionsRead()
	if m == nil {
		return b, nil
	}
	mu.Lock()
	defer mu.Unlock()

	var err error
	var nerr nonFatal

	// Fast-path for common cases: zero or one extensions.
	// Don't bother sorting the keys.
	if len(m) <= 1 {
		for id, e := range m {
			b = append(b, 1<<3|WireStartGroup)
			b = append(b, 2<<3|WireVarint)
			b = appendVarint(b, uint64(id))

			if e.value == nil || e.desc == nil {
				// Extension is only in its encoded form.
				msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
				b = append(b, 3<<3|WireBytes)
				b = append(b, msgWithLen...)
				b = append(b, 1<<3|WireEndGroup)
				continue
			}

			// We don't skip extensions that have an encoded form set,
			// because the extension value may have been mutated after
			// the last time this function was called.

			ei := u.getExtElemInfo(e.desc)
			v := e.value
			p := toAddrPointer(&v, ei.isptr)
			b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
			if !nerr.Merge(err) {
				return b, err
			}
			b = append(b, 1<<3|WireEndGroup)
		}
		return b, nerr.E
	}

	// Sort the keys to provide a deterministic encoding.
	keys := make([]int, 0, len(m))
	for k := range m {
		keys = append(keys, int(k))
	}
	sort.Ints(keys)

	for _, id := range keys {
		e := m[int32(id)]
		b = append(b, 1<<3|WireStartGroup)
		b = append(b, 2<<3|WireVarint)
		b = appendVarint(b, uint64(id))

		if e.value == nil || e.desc == nil {
			// Extension is only in its encoded form.
			msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
			b = append(b, 3<<3|WireBytes)
			b = append(b, msgWithLen...)
			b = append(b, 1<<3|WireEndGroup)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		ei := u.getExtElemInfo(e.desc)
		v := e.value
		p := toAddrPointer(&v, ei.isptr)
		b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
		b = append(b, 1<<3|WireEndGroup)
		if !nerr.Merge(err) {
			return b, err
		}
	}
	return b, nerr.E
}

// sizeV1Extensions computes the size of encoded data for a V1-API extension field.
func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {
	if m == nil {
		return 0
	}

	n := 0
	for _, e := range m {
		if e.value == nil || e.desc == nil {
			// Extension is only in its encoded form.
			n += len(e.enc)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		ei := u.getExtElemInfo(e.desc)
		v := e.value
		p := toAddrPointer(&v, ei.isptr)
		n += ei.sizer(p, ei.tagsize)
	}
	return n
}

// appendV1Extensions marshals a V1-API extension field to the end of byte slice b.
func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) {
	if m == nil {
		return b, nil
	}

	// Sort the keys to provide a deterministic encoding.
	keys := make([]int, 0, len(m))
	for k := range m {
		keys = append(keys, int(k))
	}
	sort.Ints(keys)

	var err error
	var nerr nonFatal
	for _, k := range keys {
		e := m[int32(k)]
		if e.value == nil || e.desc == nil {
			// Extension is only in its encoded form.
			b = append(b, e.enc...)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		ei := u.getExtElemInfo(e.desc)
		v := e.value
		p := toAddrPointer(&v, ei.isptr)
		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
		if !nerr.Merge(err) {
			return b, err
		}
	}
	return b, nerr.E
}

// newMarshaler is the interface representing objects that can marshal themselves.
//
// This exists to support protoc-gen-go generated messages.
// The proto package will stop type-asserting to this interface in the future.
//
// DO NOT DEPEND ON THIS.
type newMarshaler interface {
	XXX_Size() int
	XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
}

// Size returns the encoded size of a protocol buffer message.
// This is the main entry point.
func Size(pb Message) int {
	if m, ok := pb.(newMarshaler); ok {
		return m.XXX_Size()
	}
	if m, ok := pb.(Marshaler); ok {
		// If the message can marshal itself, let it do it, for compatibility.
		// NOTE: This is not efficient.
		b, _ := m.Marshal()
		return len(b)
	}
	// in case somehow we didn't generate the wrapper
	if pb == nil {
		return 0
	}
	var info InternalMessageInfo
	return info.Size(pb)
}

// Marshal takes a protocol buffer message
// and encodes it into the wire format, returning the data.
// This is the main entry point.
func Marshal(pb Message) ([]byte, error) {
	if m, ok := pb.(newMarshaler); ok {
		siz := m.XXX_Size()
		b := make([]byte, 0, siz)
		return m.XXX_Marshal(b, false)
	}
	if m, ok := pb.(Marshaler); ok {
		// If the message can marshal itself, let it do it, for compatibility.
		// NOTE: This is not efficient.
		return m.Marshal()
	}
	// in case somehow we didn't generate the wrapper
	if pb == nil {
		return nil, ErrNil
	}
	var info InternalMessageInfo
	siz := info.Size(pb)
	b := make([]byte, 0, siz)
	return info.Marshal(b, pb, false)
}

// Marshal takes a protocol buffer message
// and encodes it into the wire format, writing the result to the
// Buffer.
// This is an alternative entry point. It is not necessary to use
// a Buffer for most applications.
func (p *Buffer) Marshal(pb Message) error {
	var err error
	if p.deterministic {
		if _, ok := pb.(Marshaler); ok {
			return fmt.Errorf("proto: deterministic not supported by the Marshal method of %T", pb)
		}
	}
	if m, ok := pb.(newMarshaler); ok {
		siz := m.XXX_Size()
		p.grow(siz) // make sure buf has enough capacity
		pp := p.buf[len(p.buf) : len(p.buf) : len(p.buf)+siz]
		pp, err = m.XXX_Marshal(pp, p.deterministic)
		p.buf = append(p.buf, pp...)
		return err
	}
	if m, ok := pb.(Marshaler); ok {
		// If the message can marshal itself, let it do it, for compatibility.
		// NOTE: This is not efficient.
		var b []byte
		b, err = m.Marshal()
		p.buf = append(p.buf, b...)
		return err
	}
	// in case somehow we didn't generate the wrapper
	if pb == nil {
		return ErrNil
	}
	var info InternalMessageInfo
	siz := info.Size(pb)
	p.grow(siz) // make sure buf has enough capacity
	p.buf, err = info.Marshal(p.buf, pb, p.deterministic)
	return err
}

// grow grows the buffer's capacity, if necessary, to guarantee space for
// another n bytes. After grow(n), at least n bytes can be written to the
// buffer without another allocation.
func (p *Buffer) grow(n int) {
	need := len(p.buf) + n
	if need <= cap(p.buf) {
		return
	}
	newCap := len(p.buf) * 2
	if newCap < need {
		newCap = need
	}
	p.buf = append(make([]byte, 0, newCap), p.buf...)
}

Youez - 2016 - github.com/yon3zu
LinuXploit